Skip to content

Commit 6c4cdbe

Browse files
antfuclaude
andauthored
feat: add public getDevToolsClientContext() API (#219)
Co-authored-by: Claude Haiku 4.5 <noreply@anthropic.com>
1 parent ccc8cb4 commit 6c4cdbe

File tree

11 files changed

+95
-3
lines changed

11 files changed

+95
-3
lines changed

docs/kit/rpc.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,22 @@ export default function setup(ctx: DockClientScriptContext) {
393393
}
394394
```
395395

396+
### Global Client Context
397+
398+
Use `getDevToolsClientContext()` to access the client context (`DevToolsClientContext`) from anywhere on the client side. This is set automatically when DevTools initializes in embedded or standalone mode.
399+
400+
```ts
401+
import { getDevToolsClientContext } from '@vitejs/devtools-kit/client'
402+
403+
const ctx = getDevToolsClientContext()
404+
if (ctx) {
405+
const modules = await ctx.rpc.call('my-plugin:get-modules')
406+
}
407+
```
408+
409+
Returns `undefined` if the context has not been initialized yet.
410+
```
411+
396412
## Client-Side Functions
397413
398414
You can also define functions on the client that the server can call.

docs/kit/shared-state.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,17 @@ const state = await client.sharedState.get('my-plugin:state')
118118
console.log(state.value())
119119
```
120120

121+
You can also access shared state through the global client context:
122+
123+
```ts
124+
import { getDevToolsClientContext } from '@vitejs/devtools-kit/client'
125+
126+
const ctx = getDevToolsClientContext()
127+
if (ctx) {
128+
const state = await ctx.rpc.sharedState.get('my-plugin:state')
129+
}
130+
```
131+
121132
### Subscribing to Changes
122133

123134
Use `state.on('updated', ...)` to react to state changes:

packages/core/src/client/inject/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/// <reference lib="dom" />
33

44
import type { DockPanelStorage } from '@vitejs/devtools-kit/client'
5-
import { getDevToolsRpcClient } from '@vitejs/devtools-kit/client'
5+
import { CLIENT_CONTEXT_KEY, getDevToolsRpcClient } from '@vitejs/devtools-kit/client'
66
import { useLocalStorage } from '@vueuse/core'
77
import { createDocksContext } from '../webcomponents/state/context'
88

@@ -31,6 +31,7 @@ export async function init(): Promise<void> {
3131
rpc,
3232
state,
3333
)
34+
;(globalThis as any)[CLIENT_CONTEXT_KEY] = context
3435

3536
const { DockEmbedded } = import.meta.env.VITE_DEVTOOLS_LOCAL_DEV
3637
? await import('../webcomponents')

packages/core/src/client/standalone/App.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script setup lang="ts">
22
import type { DocksContext } from '@vitejs/devtools-kit/client'
3-
import { getDevToolsRpcClient } from '@vitejs/devtools-kit/client'
3+
import { CLIENT_CONTEXT_KEY, getDevToolsRpcClient } from '@vitejs/devtools-kit/client'
44
import DockStandalone from '../webcomponents/components/DockStandalone.vue'
55
import { createDocksContext } from '../webcomponents/state/context'
66
@@ -13,6 +13,7 @@ const context: DocksContext = await createDocksContext(
1313
'standalone',
1414
rpc,
1515
)
16+
;(globalThis as any)[CLIENT_CONTEXT_KEY] = context
1617
</script>
1718

1819
<template>

packages/kit/src/client/context.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import type { DevToolsClientContext } from './docks'
2+
3+
const CLIENT_CONTEXT_KEY = '__VITE_DEVTOOLS_CLIENT_CONTEXT__'
4+
5+
/**
6+
* Get the global DevTools client context, or `undefined` if not yet initialized.
7+
*/
8+
export function getDevToolsClientContext(): DevToolsClientContext | undefined {
9+
return (globalThis as any)[CLIENT_CONTEXT_KEY]
10+
}
11+
12+
export { CLIENT_CONTEXT_KEY }

packages/kit/src/client/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export * from './client-script'
2+
export * from './context'
23
export * from './docks'
34
export * from './rpc'

skills/vite-devtools-kit/SKILL.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,19 @@ export default function setup(ctx: DevToolsClientScriptContext) {
360360
}
361361
```
362362

363+
## Client Context
364+
365+
The global client context (`DevToolsClientContext`) provides access to the RPC client and is set automatically when DevTools initializes (embedded or standalone). Use `getDevToolsClientContext()` to access it from anywhere on the client side:
366+
367+
```ts
368+
import { getDevToolsClientContext } from '@vitejs/devtools-kit/client'
369+
370+
const ctx = getDevToolsClientContext()
371+
if (ctx) {
372+
const modules = await ctx.rpc.call('my-plugin:get-modules')
373+
}
374+
```
375+
363376
### Broadcasting to Clients
364377

365378
```ts

skills/vite-devtools-kit/references/project-structure.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,15 @@ export function useRpc() {
187187
}
188188
```
189189

190+
Alternatively, use `getDevToolsClientContext()` to access the global client context synchronously (returns `undefined` if not yet initialized):
191+
192+
```ts
193+
import { getDevToolsClientContext } from '@vitejs/devtools-kit/client'
194+
195+
const ctx = getDevToolsClientContext()
196+
// ctx?.rpc is the DevToolsRpcClient
197+
```
198+
190199
## Client App Component (src/client/App.vue)
191200

192201
```vue

skills/vite-devtools-kit/references/rpc-patterns.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,21 @@ ctx.rpc.broadcast({
119119
})
120120
```
121121

122+
## Global Client Context
123+
124+
Use `getDevToolsClientContext()` to access the client context (`DevToolsClientContext`) globally. Returns `undefined` if the context has not been initialized yet.
125+
126+
```ts
127+
import { getDevToolsClientContext } from '@vitejs/devtools-kit/client'
128+
129+
const ctx = getDevToolsClientContext()
130+
if (ctx) {
131+
await ctx.rpc.call('my-plugin:get-modules')
132+
}
133+
```
134+
135+
This is set automatically when DevTools initializes in embedded or standalone mode. For iframe pages, `getDevToolsRpcClient()` is still the recommended way to get the RPC client directly.
136+
122137
## Client Function Registration
123138

124139
```ts

skills/vite-devtools-kit/references/shared-state-patterns.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ state.mutate((draft) => {
3333
import { getDevToolsRpcClient } from '@vitejs/devtools-kit/client'
3434

3535
const client = await getDevToolsRpcClient()
36-
const state = await client.rpc.sharedState.get('my-plugin:state')
36+
const state = await client.sharedState.get('my-plugin:state')
3737

3838
// Read
3939
console.log(state.value())
@@ -44,6 +44,17 @@ state.on('updated', (newState) => {
4444
})
4545
```
4646

47+
You can also access shared state through the global client context:
48+
49+
```ts
50+
import { getDevToolsClientContext } from '@vitejs/devtools-kit/client'
51+
52+
const ctx = getDevToolsClientContext()
53+
if (ctx) {
54+
const state = await ctx.rpc.sharedState.get('my-plugin:state')
55+
}
56+
```
57+
4758
## Type-Safe Shared State
4859

4960
```ts

0 commit comments

Comments
 (0)