Skip to content

Commit 8d323f3

Browse files
committed
feat: create event bus server + client communication for devtools
1 parent 6d30053 commit 8d323f3

File tree

16 files changed

+915
-119
lines changed

16 files changed

+915
-119
lines changed

examples/react/start/package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,17 @@
2323
"@tanstack/react-router": "^1.130.2",
2424
"@tanstack/react-router-devtools": "^1.130.2",
2525
"@tanstack/react-router-with-query": "^1.130.2",
26-
"@tanstack/react-start": "^1.130.2",
26+
"@tanstack/react-start": "^1.130.15",
2727
"@tanstack/router-plugin": "^1.121.2",
2828
"prisma": "^6.13.0",
2929
"react": "^19.1.0",
3030
"react-dom": "^19.1.0",
3131
"tailwindcss": "^4.0.6",
32-
"vite-tsconfig-paths": "^5.1.4"
32+
"vite-tsconfig-paths": "^5.1.4",
33+
"zod": "^4.0.14"
3334
},
3435
"devDependencies": {
36+
"@tanstack/devtools": "workspace:^",
3537
"@testing-library/dom": "^10.4.0",
3638
"@testing-library/react": "^16.2.0",
3739
"@types/react": "^19.1.2",
@@ -43,4 +45,4 @@
4345
"vitest": "^3.1.2",
4446
"web-vitals": "^4.2.4"
4547
}
46-
}
48+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { DevtoolsClient } from '@tanstack/devtools/client'
2+
3+
const devtoolsClient = new DevtoolsClient()
4+
5+
devtoolsClient.connect()
6+
7+
export { devtoolsClient }
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { useEffect, useState } from 'react'
2+
import { devtoolsClient } from '@/client-setup'
3+
4+
export default function ClientPlugin() {
5+
const [events, setEvents] = useState<
6+
Array<{ type: string; payload: { title: string; description: string } }>
7+
>([])
8+
useEffect(() => {
9+
devtoolsClient.onAll((event) => {
10+
console.log('Received message:', event)
11+
setEvents((prev) => [...prev, event])
12+
})
13+
devtoolsClient.emit({
14+
type: 'init',
15+
payload: {
16+
title: 'Client Plugin Initialized',
17+
description: 'Listening for events',
18+
},
19+
})
20+
}, [])
21+
return (
22+
<div>
23+
<h1>Client Plugin Initialized</h1>
24+
<p>Devtools Client is connected.</p>
25+
<button
26+
onClick={() =>
27+
devtoolsClient.emit({
28+
type: 'click-event',
29+
payload: {
30+
title: 'Button Clicked',
31+
description:
32+
'This is a custom event triggered by the client plugin.',
33+
},
34+
})
35+
}
36+
>
37+
Click me bro
38+
</button>
39+
{events.map((event, i) => (
40+
<div key={i}>
41+
<h2>{event.payload.title}</h2>
42+
<p style={{ color: 'gray' }}>{event.payload.description}</p>
43+
</div>
44+
))}
45+
</div>
46+
)
47+
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { ReactQueryDevtoolsPanel } from '@tanstack/react-query-devtools'
33
import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools'
44
import { TanstackDevtools } from '@tanstack/react-devtools'
55
import { StudioPlugin } from './prisma-plugin'
6+
import ClientPlugin from './client-plugin'
67

78
const queryClient = new QueryClient()
89

@@ -24,6 +25,10 @@ export default function DevtoolsExample() {
2425
name: 'Prisma Studio',
2526
render: <StudioPlugin />,
2627
},
28+
{
29+
name: 'Client Plugin',
30+
render: <ClientPlugin />,
31+
},
2732
]}
2833
/>
2934
</QueryClientProvider>
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import {
2+
DevtoolsServer,
3+
DevtoolsPlugin,
4+
type EventMap,
5+
} from '@tanstack/devtools/server'
6+
import { z } from 'zod'
7+
const devtoolsServer = new DevtoolsServer()
8+
9+
devtoolsServer.start()
10+
11+
devtoolsServer.on('click-event', (payload) => {
12+
console.log('Click event received:', payload)
13+
})
14+
15+
devtoolsServer.onAll((e) => {
16+
console.log('All events:', e)
17+
})
18+
19+
setInterval(() => {
20+
console.log('Emitting server event...')
21+
devtoolsServer.emit({
22+
type: 'server-event',
23+
payload: {
24+
title: 'Server Event',
25+
description: 'This is a custom event emitted by the server.',
26+
},
27+
})
28+
}, 5000)
29+
30+
const eventMap = {
31+
'query-devtools:test': z.object({
32+
title: z.string(),
33+
description: z.string(),
34+
}),
35+
'query-devtools:init': z.object({
36+
title: z.string(),
37+
description: z.string(),
38+
}),
39+
'query-devtools:b': z.object({
40+
title: z.string(),
41+
description: z.string(),
42+
}),
43+
} satisfies EventMap<'query-devtools'>
44+
45+
class QueryDevtoolsPlugin extends DevtoolsPlugin<typeof eventMap> {
46+
constructor() {
47+
super({
48+
pluginId: 'query-devtools',
49+
})
50+
}
51+
}
52+
53+
const plugin = new QueryDevtoolsPlugin()
54+
/* plugin.emit({
55+
type: `query-devtools:init`,
56+
payload: {
57+
// Add your payload data here
58+
},
59+
}) */
60+
61+
plugin.onAll((e) => {
62+
if (e.type === 'query-devtools:test') {
63+
console.log('Received query-devtools:test event:', e.payload)
64+
}
65+
})
66+
plugin.on('query-devtools:test', (e) => {
67+
e.payload
68+
})
69+
70+
export { devtoolsServer }

examples/react/start/vite.config.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,23 @@ 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'
67

78
const config = defineConfig({
89
plugins: [
910
// this is the plugin that enables path aliases
1011
viteTsConfigPaths({
1112
projects: ['./tsconfig.json'],
1213
}),
14+
{
15+
name: 'custom-devtools',
16+
17+
configureServer() {
18+
devtoolsServer.on('init', (payload) => {
19+
console.log('Devtools server initialized:', payload)
20+
})
21+
},
22+
},
1323
tailwindcss(),
1424
tanstackStart({
1525
customViteReactPlugin: true,

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,4 @@
7878
"@tanstack/react-devtools": "workspace:*",
7979
"@tanstack/solid-devtools": "workspace:*"
8080
}
81-
}
81+
}

packages/devtools/package.json

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,26 @@
3232
"default": "./dist/cjs/index.cjs"
3333
}
3434
},
35+
"./server": {
36+
"import": {
37+
"types": "./dist/esm/server/index.d.ts",
38+
"default": "./dist/esm/server/index.js"
39+
},
40+
"require": {
41+
"types": "./dist/cjs/server/index.d.cts",
42+
"default": "./dist/cjs/server/index.cjs"
43+
}
44+
},
45+
"./client": {
46+
"import": {
47+
"types": "./dist/esm/client/index.d.ts",
48+
"default": "./dist/esm/client/index.js"
49+
},
50+
"require": {
51+
"types": "./dist/cjs/client/index.d.cts",
52+
"default": "./dist/cjs/client/index.cjs"
53+
}
54+
},
3555
"./package.json": "./package.json"
3656
},
3757
"sideEffects": false,
@@ -56,12 +76,16 @@
5676
"@solid-primitives/keyboard": "^1.2.8",
5777
"clsx": "^2.1.1",
5878
"goober": "^2.1.16",
59-
"solid-js": "^1.9.7"
79+
"solid-js": "^1.9.7",
80+
"ws": "^8.18.3"
6081
},
6182
"peerDependencies": {
6283
"solid-js": ">=1.9.7"
6384
},
6485
"devDependencies": {
86+
"@standard-schema/spec": "^1.0.0",
87+
"@types/node": "^22.15.2",
88+
"@types/ws": "^8.18.1",
6589
"vite-plugin-solid": "^2.11.6"
6690
}
67-
}
91+
}

0 commit comments

Comments
 (0)