Skip to content

Commit 6c8c86d

Browse files
fix: remove invalid plugins from active plugins on mount (#126)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent c591da3 commit 6c8c86d

File tree

4 files changed

+88
-2
lines changed

4 files changed

+88
-2
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { beforeEach, describe, expect, it } from 'vitest'
2+
import { TANSTACK_DEVTOOLS_STATE } from '../utils/storage'
3+
import { getStateFromLocalStorage } from './devtools-context'
4+
5+
describe('getStateFromLocalStorage', () => {
6+
beforeEach(() => {
7+
localStorage.clear()
8+
})
9+
it('should return undefined when no data in localStorage', () => {
10+
const state = getStateFromLocalStorage()
11+
expect(state).toEqual(undefined)
12+
})
13+
it('should return parsed state from localStorage and not remove valid plugins', () => {
14+
const mockState = {
15+
activePlugins: ['plugin1'],
16+
settings: {
17+
theme: 'dark',
18+
},
19+
}
20+
localStorage.setItem(TANSTACK_DEVTOOLS_STATE, JSON.stringify(mockState))
21+
const state = getStateFromLocalStorage([
22+
{
23+
id: 'plugin1',
24+
render: () => {},
25+
name: 'Plugin 1',
26+
},
27+
])
28+
expect(state).toEqual(mockState)
29+
})
30+
it('should filter out inactive plugins', () => {
31+
const mockState = {
32+
activePlugins: ['plugin1', 'plugin2'],
33+
settings: {
34+
theme: 'dark',
35+
},
36+
}
37+
localStorage.setItem(TANSTACK_DEVTOOLS_STATE, JSON.stringify(mockState))
38+
const plugins = [{ id: 'plugin1', render: () => {}, name: 'Plugin 1' }]
39+
const state = getStateFromLocalStorage(plugins)
40+
expect(state?.activePlugins).toEqual(['plugin1'])
41+
})
42+
it('should return empty plugin state if all active plugins are invalid', () => {
43+
const mockState = {
44+
activePlugins: ['plugin1', 'plugin2'],
45+
settings: {
46+
theme: 'dark',
47+
},
48+
}
49+
localStorage.setItem(TANSTACK_DEVTOOLS_STATE, JSON.stringify(mockState))
50+
const plugins = [{ id: 'plugin3', render: () => {}, name: 'Plugin 3' }]
51+
const state = getStateFromLocalStorage(plugins)
52+
expect(state?.activePlugins).toEqual([])
53+
})
54+
it('should handle invalid JSON in localStorage gracefully', () => {
55+
localStorage.setItem(TANSTACK_DEVTOOLS_STATE, 'invalid json')
56+
const state = getStateFromLocalStorage()
57+
expect(state).toEqual(undefined)
58+
})
59+
})

packages/devtools/src/context/devtools-context.tsx

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,35 @@ const generatePluginId = (plugin: TanStackDevtoolsPlugin, index: number) => {
9999
return index.toString()
100100
}
101101

102+
export function getStateFromLocalStorage(
103+
plugins?: Array<TanStackDevtoolsPlugin>,
104+
) {
105+
const existingStateString = getStorageItem(TANSTACK_DEVTOOLS_STATE)
106+
const existingState =
107+
tryParseJson<DevtoolsStore['state']>(existingStateString)
108+
const pluginIds =
109+
plugins?.map((plugin, i) => generatePluginId(plugin, i)) || []
110+
if (existingState?.activePlugins) {
111+
const originalLength = existingState.activePlugins.length
112+
// Filter out any active plugins that are no longer available
113+
existingState.activePlugins = existingState.activePlugins.filter((id) =>
114+
pluginIds.includes(id),
115+
)
116+
117+
if (existingState.activePlugins.length !== originalLength) {
118+
// If any active plugins were removed, update local storage
119+
setStorageItem(TANSTACK_DEVTOOLS_STATE, JSON.stringify(existingState))
120+
}
121+
}
122+
123+
return existingState
124+
}
125+
102126
const getExistingStateFromStorage = (
103127
config?: TanStackDevtoolsConfig,
104128
plugins?: Array<TanStackDevtoolsPlugin>,
105129
) => {
106-
const existingState = getStorageItem(TANSTACK_DEVTOOLS_STATE)
130+
const existingState = getStateFromLocalStorage()
107131
const settings = getSettings()
108132

109133
const state: DevtoolsStore = {
@@ -118,7 +142,7 @@ const getExistingStateFromStorage = (
118142
}) || [],
119143
state: {
120144
...initialState.state,
121-
...(existingState ? JSON.parse(existingState) : {}),
145+
...existingState,
122146
},
123147
settings: {
124148
...initialState.settings,

packages/devtools/src/context/devtools-store.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ export const initialState: DevtoolsStore = {
8282
urlFlag: 'tanstack-devtools',
8383
theme:
8484
typeof window !== 'undefined' &&
85+
typeof window.matchMedia !== 'undefined' &&
8586
window.matchMedia('(prefers-color-scheme: dark)').matches
8687
? 'dark'
8788
: 'light',

pnpm-lock.yaml

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)