diff --git a/packages/devtools/client/composables/client.ts b/packages/devtools/client/composables/client.ts index 6031ed9a10..46fa973720 100644 --- a/packages/devtools/client/composables/client.ts +++ b/packages/devtools/client/composables/client.ts @@ -1,13 +1,14 @@ import type { useRoute, useRouter } from '#imports' import type { NuxtDevtoolsClient, NuxtDevtoolsHostClient, NuxtDevtoolsIframeClient } from '@nuxt/devtools-kit/types' import type { Unhead } from '@unhead/schema' +import type { DevToolsRpcClient } from '@vitejs/devtools-kit/client' import type { ComputedRef } from 'vue' import { useState } from '#imports' import { useColorMode } from '@vueuse/core' import { computed, ref } from 'vue' import { renderMarkdown } from './client-services/markdown' import { renderCodeHighlight } from './client-services/shiki' -import { extendedRpcMap, rpc } from './rpc' +import { connectPromise, rpc, rpcClient } from './rpc' export function useClient() { return useState('devtools-client') @@ -59,13 +60,31 @@ export function useInjectionClient(): ComputedRef { return renderMarkdown(code) }, extendClientRpc(namespace, functions) { - extendedRpcMap.set(namespace, functions) + const register = (client: DevToolsRpcClient) => { + for (const [name, handler] of Object.entries(functions)) { + if (typeof handler === 'function') { + client.client.register({ + name: `${namespace}:${name}`, + type: 'event', + handler: handler as any, + }) + } + } + } + + if (rpcClient.value) + register(rpcClient.value) + else + void connectPromise.then(register, () => {}) return new Proxy({}, { get(_, key) { if (typeof key !== 'string') return - return (rpc as any)[`${namespace}:${key}`] + return async (...args: any[]) => { + const client = rpcClient.value || await connectPromise + return client.call(`${namespace}:${key}` as any, ...args as any) + } }, }) }, diff --git a/packages/devtools/client/composables/rpc.ts b/packages/devtools/client/composables/rpc.ts index 007e2dc73d..5c05def57d 100644 --- a/packages/devtools/client/composables/rpc.ts +++ b/packages/devtools/client/composables/rpc.ts @@ -12,11 +12,9 @@ export const clientFunctions = { // will be added in setup/client-rpc.ts } as ClientFunctions -export const extendedRpcMap = new Map() +export const rpcClient = shallowRef() -let rpcClient: DevToolsRpcClient | undefined - -const connectPromise = connectDevToolsRpc() +export const connectPromise = connectDevToolsRpc() /** * Proxy-based RPC object that provides backward-compatible `rpc.functionName()` interface. @@ -25,14 +23,7 @@ const connectPromise = connectDevToolsRpc() export const rpc = new Proxy({} as AsyncServerFunctions, { get: (_, method: string) => { return async (...args: any[]) => { - const client = rpcClient || await connectPromise - // Check extended RPC map first for namespaced functions - if (method.includes(':')) { - const [namespace, fnName] = method.split(':') as [string, string] - const extFn = extendedRpcMap.get(namespace)?.[fnName] - if (extFn) - return extFn(...args) - } + const client = rpcClient.value || await connectPromise return client.call(method as any, ...args as any) } }, @@ -42,7 +33,7 @@ async function connectDevToolsRpc(): Promise { try { const client = await getDevToolsRpcClient() - rpcClient = client + rpcClient.value = client // Register client functions so the server can call them for (const [name, handler] of Object.entries(clientFunctions)) { @@ -55,19 +46,6 @@ async function connectDevToolsRpc(): Promise { } } - // Register extended client RPC functions - for (const [namespace, fns] of extendedRpcMap) { - for (const [fnName, handler] of Object.entries(fns)) { - if (typeof handler === 'function') { - client.client.register({ - name: `${namespace}:${fnName}`, - type: 'event', - handler: handler as any, - }) - } - } - } - // eslint-disable-next-line no-console console.log('[nuxt-devtools] Connected to Vite DevTools RPC') wsConnecting.value = false @@ -87,7 +65,7 @@ async function connectDevToolsRpc(): Promise { * Used by setup/client-rpc.ts to register functions that are set up later. */ export async function registerClientFunctions() { - const client = rpcClient || await connectPromise + const client = rpcClient.value || await connectPromise for (const [name, handler] of Object.entries(clientFunctions)) { if (typeof handler === 'function') { try {