Skip to content

Commit 0e7bee5

Browse files
antfuclaude
andcommitted
feat: add public getDevToolsClientContext() API for global client context access
Adds a new public API to access the DevToolsClientContext globally from anywhere on the client side. The context is set automatically when DevTools initializes in embedded or standalone mode, and returns undefined if not yet initialized. This allows easier access to the RPC client and shared state without always requiring async getDevToolsRpcClient() calls. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
1 parent 6312023 commit 0e7bee5

File tree

10 files changed

+93
-3
lines changed

10 files changed

+93
-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)