1+ import type { Disposable } from "vscode-jsonrpc" ;
12import { type MessageConnection , RequestType } from "vscode-jsonrpc/node" ;
23import type {
34 ClientRequest ,
@@ -61,8 +62,7 @@ const FileChangeApprovalRequest = new RequestType<
6162export class CodexAppServerClient {
6263 readonly connection : MessageConnection ;
6364 private approvalHandlers = new Map < string , ApprovalHandler > ( ) ;
64- private readonly notificationHandlers = new Map < string , ( event : ServerNotification ) => void | Promise < void > > ( ) ;
65- private readonly notificationQueues = new Map < string , Promise < void > | null > ( ) ;
65+ private readonly notificationHandlers = new Set < ( event : ServerNotification ) => Promise < void > > ( ) ;
6666 private mcpStartupCompleteVersion = 0 ;
6767 private lastMcpStartupComplete : McpStartupCompleteEvent | null = null ;
6868 private readonly mcpStartupCompleteResolvers : Array < SignalResolver < McpStartupCompleteEvent > > = [ ] ;
@@ -80,7 +80,7 @@ export class CodexAppServerClient {
8080 return ;
8181 }
8282 const serverNotification = data as ServerNotification ;
83- this . notify ( serverNotification ) ;
83+ this . notifyServerNotificationHandlers ( serverNotification ) ;
8484 for ( const callback of this . codexEventHandlers ) {
8585 callback ( { eventType : "notification" , ...serverNotification } ) ;
8686 }
@@ -190,59 +190,30 @@ export class CodexAppServerClient {
190190 }
191191
192192 /**
193- * Registers a notification handler for a specific session.
194- * Replaces any existing handler for the same session, preventing handler accumulation.
193+ * Registers a notification handler for server notifications.
195194 */
196- onServerNotification ( sessionId : string , callback : ( event : ServerNotification ) => void | Promise < void > ) {
197- this . notificationHandlers . set ( sessionId , callback ) ;
198- this . notificationQueues . set ( sessionId , null ) ;
195+ onServerNotification ( callback : ( event : ServerNotification ) => Promise < void > ) : Disposable {
196+ this . notificationHandlers . add ( callback ) ;
197+ return {
198+ dispose : ( ) => {
199+ this . notificationHandlers . delete ( callback ) ;
200+ }
201+ } ;
199202 }
200203
201204 private codexEventHandlers : Array < ( event : CodexConnectionEvent ) => void > = [ ] ;
202205 onClientTransportEvent ( callback : ( event : CodexConnectionEvent ) => void ) {
203206 this . codexEventHandlers . push ( callback ) ;
204207 }
205208
206- private notify ( notification : ServerNotification ) {
207- for ( const [ sessionId , notificationHandler ] of this . notificationHandlers . entries ( ) ) {
208- const queue = this . notificationQueues . get ( sessionId ) ;
209- if ( queue ) {
210- const next = queue
211- . then ( ( ) => notificationHandler ( notification ) )
212- . catch ( ( error ) => {
213- logger . error ( "Error handling server notification" , error ) ;
214- } ) ;
215- this . notificationQueues . set ( sessionId , this . trackNotificationQueue ( sessionId , next ) ) ;
216- continue ;
217- }
218-
219- try {
220- const result = notificationHandler ( notification ) ;
221- if ( result instanceof Promise ) {
222- const next = result . catch ( ( error ) => {
223- logger . error ( "Error handling server notification" , error ) ;
224- } ) ;
225- this . notificationQueues . set ( sessionId , this . trackNotificationQueue ( sessionId , next ) ) ;
226- }
227- } catch ( error ) {
209+ private notifyServerNotificationHandlers ( notification : ServerNotification ) : void {
210+ for ( const notificationHandler of this . notificationHandlers ) {
211+ void notificationHandler ( notification ) . catch ( ( error ) => {
228212 logger . error ( "Error handling server notification" , error ) ;
229- }
213+ } ) ;
230214 }
231215 }
232216
233- async flushServerNotifications ( sessionId : string ) : Promise < void > {
234- await ( this . notificationQueues . get ( sessionId ) ?? Promise . resolve ( ) ) ;
235- }
236-
237- private trackNotificationQueue ( sessionId : string , queue : Promise < void > ) : Promise < void > {
238- const trackedQueue = queue . finally ( ( ) => {
239- if ( this . notificationQueues . get ( sessionId ) === trackedQueue ) {
240- this . notificationQueues . set ( sessionId , null ) ;
241- }
242- } ) ;
243- return trackedQueue ;
244- }
245-
246217 private resolveSignal < T > (
247218 event : T ,
248219 version : number ,
0 commit comments