@tanstack/devtools 0.6.20 → 0.6.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { initialState, DevtoolsProvider, PiPProvider } from './chunk/XFQ6P775.js';
2
- export { PLUGIN_CONTAINER_ID, PLUGIN_TITLE_CONTAINER_ID } from './chunk/XFQ6P775.js';
1
+ import { initialState, DevtoolsProvider, PiPProvider } from './chunk/XF4JFOLU.js';
2
+ export { PLUGIN_CONTAINER_ID, PLUGIN_TITLE_CONTAINER_ID } from './chunk/XF4JFOLU.js';
3
3
  import { render, createComponent, Portal } from 'solid-js/web';
4
4
  import { lazy } from 'solid-js';
5
5
  import { ClientEventBus } from '@tanstack/devtools-event-bus/client';
@@ -14,6 +14,7 @@ var TanStackDevtoolsCore = class {
14
14
  #Component;
15
15
  #eventBus;
16
16
  #eventBusConfig;
17
+ #setPlugins;
17
18
  constructor(init) {
18
19
  this.#plugins = init.plugins || [];
19
20
  this.#eventBusConfig = init.eventBusConfig;
@@ -29,7 +30,7 @@ var TanStackDevtoolsCore = class {
29
30
  const mountTo = el;
30
31
  const dispose = render(() => {
31
32
  const _self$ = this;
32
- this.#Component = lazy(() => import('./devtools/6XAY2RKM.js'));
33
+ this.#Component = lazy(() => import('./devtools/YRFZDV5N.js'));
33
34
  const Devtools = this.#Component;
34
35
  this.#eventBus = new ClientEventBus(this.#eventBusConfig);
35
36
  this.#eventBus.start();
@@ -40,6 +41,9 @@ var TanStackDevtoolsCore = class {
40
41
  get config() {
41
42
  return _self$.#config;
42
43
  },
44
+ onSetPlugins: (setPlugins) => {
45
+ _self$.#setPlugins = setPlugins;
46
+ },
43
47
  get children() {
44
48
  return createComponent(PiPProvider, {
45
49
  get children() {
@@ -70,6 +74,12 @@ var TanStackDevtoolsCore = class {
70
74
  ...this.#config,
71
75
  ...config
72
76
  };
77
+ if (config.plugins) {
78
+ this.#plugins = config.plugins;
79
+ if (this.#isMounted && this.#setPlugins) {
80
+ this.#setPlugins(config.plugins);
81
+ }
82
+ }
73
83
  }
74
84
  };
75
85
 
package/dist/server.js CHANGED
@@ -1,5 +1,5 @@
1
- import { initialState } from './chunk/XFQ6P775.js';
2
- export { PLUGIN_CONTAINER_ID, PLUGIN_TITLE_CONTAINER_ID } from './chunk/XFQ6P775.js';
1
+ import { initialState } from './chunk/XF4JFOLU.js';
2
+ export { PLUGIN_CONTAINER_ID, PLUGIN_TITLE_CONTAINER_ID } from './chunk/XF4JFOLU.js';
3
3
  import 'solid-js/web';
4
4
  import 'solid-js';
5
5
  import '@tanstack/devtools-event-bus/client';
@@ -14,6 +14,7 @@ var TanStackDevtoolsCore = class {
14
14
  #Component;
15
15
  #eventBus;
16
16
  #eventBusConfig;
17
+ #setPlugins;
17
18
  constructor(init) {
18
19
  this.#plugins = init.plugins || [];
19
20
  this.#eventBusConfig = init.eventBusConfig;
@@ -38,6 +39,12 @@ var TanStackDevtoolsCore = class {
38
39
  ...this.#config,
39
40
  ...config
40
41
  };
42
+ if (config.plugins) {
43
+ this.#plugins = config.plugins;
44
+ if (this.#isMounted && this.#setPlugins) {
45
+ this.#setPlugins(config.plugins);
46
+ }
47
+ }
41
48
  }
42
49
  };
43
50
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/devtools",
3
- "version": "0.6.20",
3
+ "version": "0.6.22",
4
4
  "description": "TanStack Devtools is a set of tools for building advanced devtools for your application.",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -49,12 +49,15 @@
49
49
  "src"
50
50
  ],
51
51
  "dependencies": {
52
+ "@solid-primitives/event-listener": "^2.4.3",
52
53
  "@solid-primitives/keyboard": "^1.3.3",
54
+ "@solid-primitives/resize-observer": "^2.1.3",
53
55
  "clsx": "^2.1.1",
54
56
  "goober": "^2.1.16",
55
57
  "solid-js": "^1.9.9",
56
- "@tanstack/devtools-event-bus": "0.3.2",
57
- "@tanstack/devtools-ui": "0.4.2"
58
+ "@tanstack/devtools-client": "0.0.3",
59
+ "@tanstack/devtools-event-bus": "0.3.3",
60
+ "@tanstack/devtools-ui": "0.4.3"
58
61
  },
59
62
  "peerDependencies": {
60
63
  "solid-js": ">=1.9.7"
@@ -0,0 +1,158 @@
1
+ import { createEffect, createMemo, createSignal } from 'solid-js'
2
+ import { createStore } from 'solid-js/store'
3
+ import { createElementSize } from '@solid-primitives/resize-observer'
4
+ import { useKeyDownList } from '@solid-primitives/keyboard'
5
+ import { createEventListener } from '@solid-primitives/event-listener'
6
+
7
+ export const SourceInspector = () => {
8
+ const highlightStateInit = () => ({
9
+ element: null as HTMLElement | null,
10
+ bounding: { width: 0, height: 0, left: 0, top: 0 },
11
+ dataSource: '',
12
+ })
13
+
14
+ const [highlightState, setHighlightState] = createStore(highlightStateInit())
15
+ const resetHighlight = () => {
16
+ setHighlightState(highlightStateInit())
17
+ }
18
+
19
+ const [nameTagRef, setNameTagRef] = createSignal<HTMLDivElement | null>(null)
20
+ const nameTagSize = createElementSize(() => nameTagRef())
21
+
22
+ const [mousePosition, setMousePosition] = createStore({ x: 0, y: 0 })
23
+ createEventListener(document, 'mousemove', (e) => {
24
+ setMousePosition({ x: e.clientX, y: e.clientY })
25
+ })
26
+
27
+ const downList = useKeyDownList()
28
+ const isHighlightingKeysHeld = createMemo(() => {
29
+ const keys = downList()
30
+ const isShiftHeld = keys.includes('SHIFT')
31
+ const isCtrlHeld = keys.includes('CONTROL')
32
+ const isMetaHeld = keys.includes('META')
33
+ return isShiftHeld && (isCtrlHeld || isMetaHeld)
34
+ })
35
+
36
+ createEffect(() => {
37
+ if (!isHighlightingKeysHeld()) {
38
+ resetHighlight()
39
+ return
40
+ }
41
+
42
+ const target = document.elementFromPoint(mousePosition.x, mousePosition.y)
43
+
44
+ if (!(target instanceof HTMLElement)) {
45
+ resetHighlight()
46
+ return
47
+ }
48
+
49
+ if (target === highlightState.element) {
50
+ return
51
+ }
52
+
53
+ const dataSource = target.getAttribute('data-tsd-source')
54
+ if (!dataSource) {
55
+ resetHighlight()
56
+ return
57
+ }
58
+
59
+ const rect = target.getBoundingClientRect()
60
+ const bounding = {
61
+ width: rect.width,
62
+ height: rect.height,
63
+ left: rect.left,
64
+ top: rect.top,
65
+ }
66
+
67
+ setHighlightState({
68
+ element: target,
69
+ bounding,
70
+ dataSource,
71
+ })
72
+ })
73
+
74
+ createEventListener(document, 'click', (e) => {
75
+ if (!highlightState.element) return
76
+
77
+ window.getSelection()?.removeAllRanges()
78
+ e.preventDefault()
79
+ e.stopPropagation()
80
+
81
+ fetch(
82
+ `${location.origin}/__tsd/open-source?source=${encodeURIComponent(
83
+ highlightState.dataSource,
84
+ )}`,
85
+ ).catch(() => {})
86
+ })
87
+
88
+ const currentElementBoxStyles = createMemo(() => {
89
+ if (highlightState.element) {
90
+ return {
91
+ display: 'block',
92
+ width: `${highlightState.bounding.width}px`,
93
+ height: `${highlightState.bounding.height}px`,
94
+ left: `${highlightState.bounding.left}px`,
95
+ top: `${highlightState.bounding.top}px`,
96
+
97
+ 'background-color': 'oklch(55.4% 0.046 257.417 /0.25)',
98
+ transition: 'all 0.05s linear',
99
+ position: 'fixed' as const,
100
+ 'z-index': 9999,
101
+ }
102
+ }
103
+ return {
104
+ display: 'none',
105
+ }
106
+ })
107
+
108
+ const fileNameStyles = createMemo(() => {
109
+ if (highlightState.element && nameTagRef()) {
110
+ const windowWidth = window.innerWidth
111
+ const nameTagHeight = nameTagSize.height || 26
112
+ const nameTagWidth = nameTagSize.width || 0
113
+ let left = highlightState.bounding.left
114
+ let top = highlightState.bounding.top - nameTagHeight - 4
115
+
116
+ if (top < 0) {
117
+ top = highlightState.bounding.top + highlightState.bounding.height + 4
118
+ }
119
+
120
+ if (left + nameTagWidth > windowWidth) {
121
+ left = windowWidth - nameTagWidth - 4
122
+ }
123
+
124
+ if (left < 0) {
125
+ left = 4
126
+ }
127
+
128
+ return {
129
+ position: 'fixed' as const,
130
+ left: `${left}px`,
131
+ top: `${top}px`,
132
+ 'background-color': 'oklch(55.4% 0.046 257.417 /0.80)',
133
+ color: 'white',
134
+ padding: '2px 4px',
135
+ fontSize: '12px',
136
+ 'border-radius': '2px',
137
+ 'z-index': 10000,
138
+ visibility: 'visible' as const,
139
+ transition: 'all 0.05s linear',
140
+ }
141
+ }
142
+ return {
143
+ display: 'none',
144
+ }
145
+ })
146
+
147
+ return (
148
+ <>
149
+ <div
150
+ ref={setNameTagRef}
151
+ style={{ ...fileNameStyles(), 'pointer-events': 'none' }}
152
+ >
153
+ {highlightState.dataSource}
154
+ </div>
155
+ <div style={{ ...currentElementBoxStyles(), 'pointer-events': 'none' }} />
156
+ </>
157
+ )
158
+ }
@@ -1,4 +1,4 @@
1
- import { createContext } from 'solid-js'
1
+ import { createContext, createEffect } from 'solid-js'
2
2
  import { createStore } from 'solid-js/store'
3
3
  import { tryParseJson } from '../utils/sanitize'
4
4
  import {
@@ -76,6 +76,9 @@ interface ContextProps {
76
76
  children: JSX.Element
77
77
  plugins?: Array<TanStackDevtoolsPlugin>
78
78
  config?: TanStackDevtoolsConfig
79
+ onSetPlugins?: (
80
+ setPlugins: (plugins: Array<TanStackDevtoolsPlugin>) => void,
81
+ ) => void
79
82
  }
80
83
 
81
84
  const getSettings = () => {
@@ -161,6 +164,26 @@ export const DevtoolsProvider = (props: ContextProps) => {
161
164
  getExistingStateFromStorage(props.config, props.plugins),
162
165
  )
163
166
 
167
+ // Provide a way for the core to update plugins reactively
168
+ const updatePlugins = (newPlugins: Array<TanStackDevtoolsPlugin>) => {
169
+ const pluginsWithIds = newPlugins.map((plugin, i) => {
170
+ const id = generatePluginId(plugin, i)
171
+ return {
172
+ ...plugin,
173
+ id,
174
+ }
175
+ })
176
+
177
+ setStore('plugins', pluginsWithIds)
178
+ }
179
+
180
+ // Call the callback to give core access to updatePlugins
181
+ createEffect(() => {
182
+ if (props.onSetPlugins) {
183
+ props.onSetPlugins(updatePlugins)
184
+ }
185
+ })
186
+
164
187
  const value = {
165
188
  store,
166
189
  setStore: (
package/src/core.tsx CHANGED
@@ -50,6 +50,7 @@ export class TanStackDevtoolsCore {
50
50
  #Component: any
51
51
  #eventBus: ClientEventBus | undefined
52
52
  #eventBusConfig: ClientEventBusConfig | undefined
53
+ #setPlugins?: (plugins: Array<TanStackDevtoolsPlugin>) => void
53
54
 
54
55
  constructor(init: TanStackDevtoolsInit) {
55
56
  this.#plugins = init.plugins || []
@@ -74,7 +75,13 @@ export class TanStackDevtoolsCore {
74
75
  this.#eventBus = new ClientEventBus(this.#eventBusConfig)
75
76
  this.#eventBus.start()
76
77
  return (
77
- <DevtoolsProvider plugins={this.#plugins} config={this.#config}>
78
+ <DevtoolsProvider
79
+ plugins={this.#plugins}
80
+ config={this.#config}
81
+ onSetPlugins={(setPlugins) => {
82
+ this.#setPlugins = setPlugins
83
+ }}
84
+ >
78
85
  <PiPProvider>
79
86
  <Portal mount={mountTo}>
80
87
  <Devtools />
@@ -102,6 +109,13 @@ export class TanStackDevtoolsCore {
102
109
  ...this.#config,
103
110
  ...config,
104
111
  }
112
+ if (config.plugins) {
113
+ this.#plugins = config.plugins
114
+ // Update the reactive store if mounted
115
+ if (this.#isMounted && this.#setPlugins) {
116
+ this.#setPlugins(config.plugins)
117
+ }
118
+ }
105
119
  }
106
120
  }
107
121
 
package/src/devtools.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import { Show, createEffect, createSignal, onCleanup } from 'solid-js'
1
+ import { Show, createEffect, createSignal } from 'solid-js'
2
2
  import { createShortcut } from '@solid-primitives/keyboard'
3
3
  import { Portal } from 'solid-js/web'
4
4
  import { ThemeContextProvider } from '@tanstack/devtools-ui'
@@ -18,6 +18,7 @@ import { TabContent } from './components/tab-content'
18
18
  import { keyboardModifiers } from './context/devtools-store'
19
19
  import { getAllPermutations } from './utils/sanitize'
20
20
  import { usePiPWindow } from './context/pip-context'
21
+ import { SourceInspector } from './components/source-inspector'
21
22
 
22
23
  export default function DevTools() {
23
24
  const { settings } = useDevtoolsSettings()
@@ -159,33 +160,6 @@ export default function DevTools() {
159
160
  }
160
161
  })
161
162
 
162
- createEffect(() => {
163
- // this will only work with the Vite plugin
164
- const openSourceHandler = (e: Event) => {
165
- const isShiftHeld = (e as KeyboardEvent).shiftKey
166
- const isCtrlHeld =
167
- (e as KeyboardEvent).ctrlKey || (e as KeyboardEvent).metaKey
168
- if (!isShiftHeld || !isCtrlHeld) return
169
-
170
- if (e.target instanceof HTMLElement) {
171
- const dataSource = e.target.getAttribute('data-tsd-source')
172
- window.getSelection()?.removeAllRanges()
173
- if (dataSource) {
174
- e.preventDefault()
175
- e.stopPropagation()
176
- fetch(
177
- `${location.origin}/__tsd/open-source?source=${encodeURIComponent(
178
- dataSource,
179
- )}`,
180
- ).catch(() => {})
181
- }
182
- }
183
- }
184
- window.addEventListener('click', openSourceHandler)
185
- onCleanup(() => {
186
- window.removeEventListener('click', openSourceHandler)
187
- })
188
- })
189
163
  const { theme } = useTheme()
190
164
 
191
165
  return (
@@ -216,6 +190,7 @@ export default function DevTools() {
216
190
  </ContentPanel>
217
191
  </MainPanel>
218
192
  </Show>
193
+ <SourceInspector />
219
194
  </div>
220
195
  </Portal>
221
196
  </ThemeContextProvider>