Skip to content

Commit 4853d04

Browse files
fix(devtools): let birpc be singlesource of turth for server<->client comms (#978)
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
1 parent cf8d9c5 commit 4853d04

File tree

2 files changed

+27
-30
lines changed

2 files changed

+27
-30
lines changed

‎packages/devtools/client/composables/client.ts‎

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import type { useRoute, useRouter } from '#imports'
22
import type { NuxtDevtoolsClient, NuxtDevtoolsHostClient, NuxtDevtoolsIframeClient } from '@nuxt/devtools-kit/types'
33
import type { Unhead } from '@unhead/schema'
4+
import type { DevToolsRpcClient } from '@vitejs/devtools-kit/client'
45
import type { ComputedRef } from 'vue'
56
import { useState } from '#imports'
67
import { useColorMode } from '@vueuse/core'
78
import { computed, ref } from 'vue'
89
import { renderMarkdown } from './client-services/markdown'
910
import { renderCodeHighlight } from './client-services/shiki'
10-
import { extendedRpcMap, rpc } from './rpc'
11+
import { connectPromise, rpc, rpcClient } from './rpc'
1112

1213
export function useClient() {
1314
return useState<NuxtDevtoolsHostClient>('devtools-client')
@@ -59,13 +60,31 @@ export function useInjectionClient(): ComputedRef<NuxtDevtoolsIframeClient> {
5960
return renderMarkdown(code)
6061
},
6162
extendClientRpc(namespace, functions) {
62-
extendedRpcMap.set(namespace, functions)
63+
const register = (client: DevToolsRpcClient) => {
64+
for (const [name, handler] of Object.entries(functions)) {
65+
if (typeof handler === 'function') {
66+
client.client.register({
67+
name: `${namespace}:${name}`,
68+
type: 'event',
69+
handler: handler as any,
70+
})
71+
}
72+
}
73+
}
74+
75+
if (rpcClient.value)
76+
register(rpcClient.value)
77+
else
78+
void connectPromise.then(register, () => {})
6379

6480
return new Proxy({}, {
6581
get(_, key) {
6682
if (typeof key !== 'string')
6783
return
68-
return (rpc as any)[`${namespace}:${key}`]
84+
return async (...args: any[]) => {
85+
const client = rpcClient.value || await connectPromise
86+
return client.call(`${namespace}:${key}` as any, ...args as any)
87+
}
6988
},
7089
})
7190
},

‎packages/devtools/client/composables/rpc.ts‎

Lines changed: 5 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,9 @@ export const clientFunctions = {
1414
// will be added in setup/client-rpc.ts
1515
} as ClientFunctions
1616

17-
export const extendedRpcMap = new Map<string, any>()
17+
export const rpcClient = shallowRef<DevToolsRpcClient>()
1818

19-
let rpcClient: DevToolsRpcClient | undefined
20-
21-
const connectPromise = connectDevToolsRpc()
19+
export const connectPromise = connectDevToolsRpc()
2220

2321
/**
2422
* Proxy-based RPC object that provides backward-compatible `rpc.functionName()` interface.
@@ -27,14 +25,7 @@ const connectPromise = connectDevToolsRpc()
2725
export const rpc = new Proxy({} as AsyncServerFunctions, {
2826
get: (_, method: string) => {
2927
return async (...args: any[]) => {
30-
const client = rpcClient || await connectPromise
31-
// Check extended RPC map first for namespaced functions
32-
if (method.includes(':')) {
33-
const [namespace, fnName] = method.split(':') as [string, string]
34-
const extFn = extendedRpcMap.get(namespace)?.[fnName]
35-
if (extFn)
36-
return extFn(...args)
37-
}
28+
const client = rpcClient.value || await connectPromise
3829
return client.call(method as any, ...args as any)
3930
}
4031
},
@@ -44,7 +35,7 @@ async function connectDevToolsRpc(): Promise<DevToolsRpcClient> {
4435
try {
4536
const client = await getDevToolsRpcClient()
4637

47-
rpcClient = client
38+
rpcClient.value = client
4839

4940
// Register client functions so the server can call them
5041
for (const [name, handler] of Object.entries(clientFunctions)) {
@@ -57,19 +48,6 @@ async function connectDevToolsRpc(): Promise<DevToolsRpcClient> {
5748
}
5849
}
5950

60-
// Register extended client RPC functions
61-
for (const [namespace, fns] of extendedRpcMap) {
62-
for (const [fnName, handler] of Object.entries(fns)) {
63-
if (typeof handler === 'function') {
64-
client.client.register({
65-
name: `${namespace}:${fnName}`,
66-
type: 'event',
67-
handler: handler as any,
68-
})
69-
}
70-
}
71-
}
72-
7351
// eslint-disable-next-line no-console
7452
console.log('[nuxt-devtools] Connected to Vite DevTools RPC')
7553
wsConnecting.value = false
@@ -90,7 +68,7 @@ async function connectDevToolsRpc(): Promise<DevToolsRpcClient> {
9068
* Used by setup/client-rpc.ts to register functions that are set up later.
9169
*/
9270
export async function registerClientFunctions() {
93-
const client = rpcClient || await connectPromise
71+
const client = rpcClient.value || await connectPromise
9472
for (const [name, handler] of Object.entries(clientFunctions)) {
9573
if (typeof handler === 'function') {
9674
try {

0 commit comments

Comments
 (0)