Skip to content

Commit 06553f8

Browse files
committed
feat: improve server/client logging via flag, fix bugs and duplicate events
1 parent f1b9a89 commit 06553f8

File tree

10 files changed

+167
-87
lines changed

10 files changed

+167
-87
lines changed

examples/react/start/src/components/client-plugin.tsx

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,26 @@
11
import { queryPlugin } from '@/plugin'
22
import { useEffect, useState } from 'react'
3-
queryPlugin.on('query-devtools:test', (event) => {
4-
console.log('Received message in here:', event)
5-
})
3+
64
export default function ClientPlugin() {
7-
const [events] = useState<
5+
const [events, setEvents] = useState<
86
Array<{ type: string; payload: { title: string; description: string } }>
97
>([])
8+
useEffect(() => {
9+
const cleanup = queryPlugin.on('query-devtools:test', (event) => {
10+
console.log('Received message in here:', event)
11+
setEvents((prev) => [...prev, event])
12+
})
1013

14+
return cleanup
15+
}, [])
1116
return (
1217
<div>
1318
<h1>Client Plugin Initialized</h1>
1419
<p>Devtools Client is connected.</p>
1520
<button
16-
onClick={() =>
21+
className="bg-blue-500 text-white px-4 py-2 rounded"
22+
onClick={() => {
23+
console.log('Button clicked, emitting event')
1724
queryPlugin.emit({
1825
type: 'query-devtools:test',
1926
payload: {
@@ -22,9 +29,9 @@ export default function ClientPlugin() {
2229
'This is a custom event triggered by the client plugin.',
2330
},
2431
})
25-
}
32+
}}
2633
>
27-
Click me bro
34+
Click me
2835
</button>
2936
{events.map((event, i) => (
3037
<div key={i}>

examples/react/start/src/components/devtools.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export default function DevtoolsExample() {
1212
<>
1313
<QueryClientProvider client={queryClient}>
1414
<TanstackDevtools
15-
hasDevtoolsServer={true}
15+
hasDevtoolsServer={false}
1616
plugins={[
1717
{
1818
name: 'Tanstack Query',

examples/react/start/vite.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { tanstackStart } from '@tanstack/react-start/plugin/vite'
33
import viteReact from '@vitejs/plugin-react'
44
import viteTsConfigPaths from 'vite-tsconfig-paths'
55
import tailwindcss from '@tailwindcss/vite'
6-
import { devtoolsServer } from './src/server-setup'
6+
//import { devtoolsServer } from './src/server-setup'
77

88
const config = defineConfig({
99
plugins: [

packages/devtools/src/core.tsx

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,24 @@ import type {
88
TanStackDevtoolsPlugin,
99
} from './context/devtools-context'
1010

11+
export interface EventBusConfig {
12+
/**
13+
* Optional flag to indicate if the devtools server event bus is available to connect to.
14+
* This is used to determine if the devtools can connect to the server for real-time event streams.
15+
*/
16+
hasServer?: boolean
17+
18+
/**
19+
* Optional flag to enable debug mode for the event bus.
20+
*/
21+
debug?: boolean
22+
23+
/**
24+
* Optional port to connect to the devtools server event bus.
25+
* Defaults to 42069.
26+
*/
27+
port?: number
28+
}
1129
export interface TanStackDevtoolsInit {
1230
/**
1331
* Configuration for the devtools shell. These configuration options are used to set the
@@ -35,11 +53,7 @@ export interface TanStackDevtoolsInit {
3553
* ```
3654
*/
3755
plugins?: Array<TanStackDevtoolsPlugin>
38-
/**
39-
* Optional flag to indicate if the devtools server is available.
40-
* This is used to determine if the devtools can connect to the server for real-time event streams.
41-
*/
42-
hasDevtoolsServer?: boolean
56+
eventBusConfig?: EventBusConfig
4357
}
4458

4559
export class TanStackDevtoolsCore {
@@ -51,11 +65,11 @@ export class TanStackDevtoolsCore {
5165
#dispose?: () => void
5266
#Component: any
5367
#eventBus: TanstackDevtoolsClientEventBus | undefined
54-
#hasDevtoolsServer = false
68+
#eventBusConfig: EventBusConfig | undefined
5569

5670
constructor(init: TanStackDevtoolsInit) {
5771
this.#plugins = init.plugins || []
58-
this.#hasDevtoolsServer = init.hasDevtoolsServer ?? false
72+
this.#eventBusConfig = init.eventBusConfig
5973
this.#config = {
6074
...this.#config,
6175
...init.config,
@@ -69,10 +83,10 @@ export class TanStackDevtoolsCore {
6983
const mountTo = el
7084
const dispose = render(() => {
7185
this.#Component = lazy(() => import('./devtools'))
72-
86+
const { hasServer, ...rest } = this.#eventBusConfig || {}
7387
const Devtools = this.#Component
74-
this.#eventBus = new TanstackDevtoolsClientEventBus()
75-
this.#eventBus.start(this.#hasDevtoolsServer)
88+
this.#eventBus = new TanstackDevtoolsClientEventBus(rest)
89+
this.#eventBus.start(hasServer)
7690
return (
7791
<DevtoolsProvider plugins={this.#plugins} config={this.#config}>
7892
<Portal mount={mountTo}>

packages/devtools/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export { PLUGIN_CONTAINER_ID, PLUGIN_TITLE_CONTAINER_ID } from './constants'
22
export { TanStackDevtoolsCore } from './core'
3-
export type { TanStackDevtoolsInit } from './core'
3+
export type { TanStackDevtoolsInit, EventBusConfig } from './core'
44
export type {
55
TanStackDevtoolsPlugin,
66
TanStackDevtoolsConfig,

packages/event-bus-plugin/src/plugin.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,25 +32,41 @@ export class TanstackDevtoolsEventSubscription<
3232
> {
3333
#pluginId: TPluginId
3434
#eventTarget: () => EventTarget
35-
36-
constructor({ pluginId }: { pluginId: TPluginId }) {
35+
#debug: boolean
36+
constructor({
37+
pluginId,
38+
debug = false,
39+
}: {
40+
pluginId: TPluginId
41+
debug?: boolean
42+
}) {
3743
this.#pluginId = pluginId
3844
this.#eventTarget = this.getGlobalTarget
45+
this.#debug = debug
46+
this.debugLog(' Initializing event subscription for plugin', this.#pluginId)
3947
}
4048

49+
private debugLog(...args: Array<any>) {
50+
if (this.#debug) {
51+
console.log(`🌴 [tanstack-devtools:${this.#pluginId}-plugin]`, ...args)
52+
}
53+
}
4154
private getGlobalTarget() {
4255
// CLient event target is the window object
4356
if (typeof window !== 'undefined') {
57+
this.debugLog('Using window as event target')
4458
return window
4559
}
4660
// server one is the global event target
4761
if (
4862
typeof globalThis !== 'undefined' &&
4963
globalThis.__TANSTACK_EVENT_TARGET__
5064
) {
65+
this.debugLog('Using global event target')
5166
return globalThis.__TANSTACK_EVENT_TARGET__
5267
}
5368

69+
this.debugLog('Using new EventTarget as fallback')
5470
return new EventTarget()
5571
}
5672

@@ -59,7 +75,7 @@ export class TanstackDevtoolsEventSubscription<
5975
}
6076

6177
private emitEventToBus(event: TanStackDevtoolsEvent<string, any>) {
62-
console.log('🌴 [tanstack-devtools] Emitting event to client bus', event)
78+
this.debugLog('Emitting event to client bus', event)
6379
this.#eventTarget().dispatchEvent(
6480
new CustomEvent('tanstack-dispatch-event', { detail: event }),
6581
)
@@ -84,14 +100,11 @@ export class TanstackDevtoolsEventSubscription<
84100
) => void,
85101
) {
86102
const handler = (e: Event) => {
87-
console.log(
88-
'🌴 [tanstack-devtools] Received event from bus',
89-
(e as CustomEvent).detail,
90-
)
103+
this.debugLog('Received event from bus', (e as CustomEvent).detail)
91104
cb((e as CustomEvent).detail)
92105
}
93106
this.#eventTarget().addEventListener(eventName as string, handler)
94-
console.log('🌴 [tanstack-devtools] Registered event to bus', eventName)
107+
this.debugLog('Registered event to bus', eventName)
95108
return () => {
96109
this.#eventTarget().removeEventListener(eventName as string, handler)
97110
}

packages/event-bus/src/client/client.ts

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,38 +9,43 @@ export class TanstackDevtoolsClientEventBus {
99
#socket: WebSocket | null
1010
#eventSource: EventSource | null
1111
#eventTarget: EventTarget
12+
#debug: boolean
1213
#dispatcher = (e: Event) => {
13-
const event = (e as CustomEvent).detail as TanStackDevtoolsEvent<
14-
string,
15-
any
16-
>
14+
const event = (e as CustomEvent).detail
1715
this.emitToServer(event)
1816
this.emitToClients(event)
1917
}
20-
constructor({ port = 42069 } = {}) {
18+
constructor({ port = 42069, debug = false } = {}) {
19+
this.#debug = debug
2120
this.#eventSource = null
2221
this.#port = port
2322
this.#socket = null
2423
this.#eventTarget = this.getGlobalTarget()
24+
this.debugLog('Initializing client event bus')
2525
}
2626

2727
private emitToClients(event: TanStackDevtoolsEvent<string>) {
28-
console.log('🌴 [tanstack-devtools] Emitting event from client bus', event)
29-
this.#eventTarget.dispatchEvent(
30-
new CustomEvent(event.type, { detail: event }),
31-
)
32-
this.#eventTarget.dispatchEvent(
33-
new CustomEvent('tanstack-devtools-global', { detail: event }),
34-
)
28+
this.debugLog('Emitting event from client bus', event)
29+
const specificEvent = new CustomEvent(event.type, { detail: event })
30+
this.debugLog('Emitting event to specific client listeners', specificEvent)
31+
this.#eventTarget.dispatchEvent(specificEvent)
32+
const globalEvent = new CustomEvent('tanstack-devtools-global', {
33+
detail: event,
34+
})
35+
this.debugLog('Emitting event to global client listeners', globalEvent)
36+
this.#eventTarget.dispatchEvent(globalEvent)
3537
}
3638

3739
private emitToServer(event: TanStackDevtoolsEvent<string, any>) {
3840
const json = JSON.stringify(event)
3941
// try to emit it to the event bus first
4042
if (this.#socket && this.#socket.readyState === WebSocket.OPEN) {
43+
this.debugLog('Emitting event to server via WS', event)
4144
this.#socket.send(json)
4245
// try to emit to SSE if WebSocket is not available (this will only happen on the client side)
4346
} else if (this.#eventSource) {
47+
this.debugLog('Emitting event to server via SSE', event)
48+
4449
fetch(`http://localhost:${this.#port}/__devtools/send`, {
4550
method: 'POST',
4651
headers: { 'Content-Type': 'application/json' },
@@ -49,7 +54,7 @@ export class TanstackDevtoolsClientEventBus {
4954
}
5055
}
5156
start(hasServer?: boolean) {
52-
console.log('🌴 [tanstack-devtools] Starting client event bus')
57+
this.debugLog('Starting client event bus')
5358
if (typeof window === 'undefined') {
5459
return
5560
}
@@ -63,6 +68,7 @@ export class TanstackDevtoolsClientEventBus {
6368
)
6469
}
6570
stop() {
71+
this.debugLog('Stopping client event bus')
6672
if (typeof window === 'undefined') {
6773
return
6874
}
@@ -82,21 +88,36 @@ export class TanstackDevtoolsClientEventBus {
8288

8389
return new EventTarget()
8490
}
91+
private debugLog(...messages: Array<any>) {
92+
if (this.#debug) {
93+
console.log('🌴 [tanstack-devtools:client-bus]', ...messages)
94+
}
95+
}
8596
private connectSSE() {
97+
this.debugLog('Connecting to SSE server')
8698
this.#eventSource = new EventSource(
8799
`http://localhost:${this.#port}/__devtools/sse`,
88100
)
89-
this.#eventSource.onmessage = (e) => this.handleEventReceived(e.data)
101+
this.#eventSource.onmessage = (e) => {
102+
this.debugLog('Received message from SSE server', e.data)
103+
this.handleEventReceived(e.data)
104+
}
90105
}
91106

92107
private connectWebSocket() {
108+
this.debugLog('Connecting to WebSocket server')
109+
93110
this.#socket = new WebSocket(`ws://localhost:${this.#port}/__devtools/ws`)
94-
this.#socket.onmessage = (e) => this.handleEventReceived(e.data)
111+
this.#socket.onmessage = (e) => {
112+
this.debugLog('Received message from server', e.data)
113+
this.handleEventReceived(e.data)
114+
}
95115
this.#socket.onclose = () => {
116+
this.debugLog('WebSocket connection closed')
96117
this.#socket = null
97118
}
98119
this.#socket.onerror = () => {
99-
// Prevent default error logging
120+
this.debugLog('WebSocket connection error')
100121
}
101122
}
102123

0 commit comments

Comments
 (0)