11/* eslint-disable no-console */
2- import type { ConnectionMeta , DevToolsNodeContext , DevToolsRpcClientFunctions , DevToolsRpcServerFunctions } from '@vitejs/devtools-kit'
2+ import type { ConnectionMeta , DevToolsNodeContext , DevToolsNodeRpcSession , DevToolsRpcClientFunctions , DevToolsRpcServerFunctions } from '@vitejs/devtools-kit'
33import type { WebSocket } from 'ws'
44import type { RpcFunctionsHost } from './host-functions'
5+ import { AsyncLocalStorage } from 'node:async_hooks'
56import { createRpcServer } from '@vitejs/devtools-rpc'
67import { createWsRpcPreset } from '@vitejs/devtools-rpc/presets/ws/server'
78import c from 'ansis'
@@ -25,16 +26,18 @@ export async function createWsServer(options: CreateWsServerOptions) {
2526
2627 const preset = createWsRpcPreset ( {
2728 port : port ! ,
28- onConnected : ( ws ) => {
29+ onConnected : ( ws , meta ) => {
2930 wsClients . add ( ws )
30- console . log ( c . green `${ MARK_CHECK } Websocket client connected` )
31+ console . log ( c . green `${ MARK_CHECK } Websocket client [ ${ meta . id } ] connected` )
3132 } ,
32- onDisconnected : ( ws ) => {
33+ onDisconnected : ( ws , meta ) => {
3334 wsClients . delete ( ws )
34- console . log ( c . red `${ MARK_CHECK } Websocket client disconnected` )
35+ console . log ( c . red `${ MARK_CHECK } Websocket client [ ${ meta . id } ] disconnected` )
3536 } ,
3637 } )
3738
39+ const asyncStorage = new AsyncLocalStorage < DevToolsNodeRpcSession > ( )
40+
3841 const rpcGroup = createRpcServer < DevToolsRpcClientFunctions , DevToolsRpcServerFunctions > (
3942 rpcHost . functions ,
4043 {
@@ -49,21 +52,35 @@ export async function createWsServer(options: CreateWsServerOptions) {
4952 console . error ( error )
5053 } ,
5154 resolver ( name , fn ) {
52- if ( name . startsWith ( ANONYMOUS_SCOPE ) )
53- return fn
54-
55- if ( ! this . $meta . isTrusted ) {
55+ // Block unauthorized access to non-anonymous methods
56+ if ( ! name . startsWith ( ANONYMOUS_SCOPE ) && ! this . $meta . isTrusted ) {
5657 return ( ) => {
5758 throw new Error ( `Unauthorized access to method ${ JSON . stringify ( name ) } , please trust this client first` )
5859 }
5960 }
60- return fn
61+
62+ // If the function is not found, return undefined
63+ if ( ! fn )
64+ return undefined
65+
66+ // Register AsyncContext for the current RPC call
67+ // eslint-disable-next-line ts/no-this-alias
68+ const rpc = this
69+ return async function ( this : any , ...args ) {
70+ return await asyncStorage . run ( {
71+ rpc,
72+ meta : rpc . $meta ,
73+ } , async ( ) => {
74+ return ( await fn ) . apply ( this , args )
75+ } )
76+ }
6177 } ,
6278 } ,
6379 } ,
6480 )
6581
66- rpcHost . rpcGroup = rpcGroup
82+ rpcHost . _rpcGroup = rpcGroup
83+ rpcHost . _asyncStorage = asyncStorage
6784
6885 const getConnectionMeta = async ( ) : Promise < ConnectionMeta > => {
6986 return {
0 commit comments