Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 22 additions & 3 deletions packages/devtools/client/composables/client.ts
Original file line number Diff line number Diff line change
@@ -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<NuxtDevtoolsHostClient>('devtools-client')
Expand Down Expand Up @@ -59,13 +60,31 @@ export function useInjectionClient(): ComputedRef<NuxtDevtoolsIframeClient> {
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)
}
},
})
},
Expand Down
32 changes: 5 additions & 27 deletions packages/devtools/client/composables/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@ export const clientFunctions = {
// will be added in setup/client-rpc.ts
} as ClientFunctions

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

let rpcClient: DevToolsRpcClient | undefined

const connectPromise = connectDevToolsRpc()
export const connectPromise = connectDevToolsRpc()

/**
* Proxy-based RPC object that provides backward-compatible `rpc.functionName()` interface.
Expand All @@ -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)
}
},
Expand All @@ -42,7 +33,7 @@ async function connectDevToolsRpc(): Promise<DevToolsRpcClient> {
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)) {
Expand All @@ -55,19 +46,6 @@ async function connectDevToolsRpc(): Promise<DevToolsRpcClient> {
}
}

// 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
Expand All @@ -87,7 +65,7 @@ async function connectDevToolsRpc(): Promise<DevToolsRpcClient> {
* 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 {
Expand Down
Loading