@@ -16,7 +16,6 @@ import type {
1616 Notification ,
1717 NotificationMethod ,
1818 NotificationTypeMap ,
19- Progress ,
2019 ProgressNotification ,
2120 RelatedTaskMetadata ,
2221 Request ,
@@ -51,14 +50,11 @@ import {
5150import type { AnySchema , SchemaOutput } from '../util/zodCompat.js' ;
5251import { safeParse } from '../util/zodCompat.js' ;
5352import { parseWithCompat } from '../util/zodJsonSchemaCompat.js' ;
53+ import type { ProgressCallback } from './progressManager.js' ;
54+ import { ProgressManager } from './progressManager.js' ;
5455import type { ResponseMessage } from './responseMessage.js' ;
5556import type { Transport , TransportSendOptions } from './transport.js' ;
5657
57- /**
58- * Callback for progress notifications.
59- */
60- export type ProgressCallback = ( progress : Progress ) => void ;
61-
6258/**
6359 * Additional initialization options.
6460 */
@@ -330,13 +326,10 @@ export abstract class Protocol<SendRequestT extends Request, SendNotificationT e
330326 private _requestHandlerAbortControllers : Map < RequestId , AbortController > = new Map ( ) ;
331327 private _notificationHandlers : Map < string , ( notification : JSONRPCNotification ) => Promise < void > > = new Map ( ) ;
332328 private _responseHandlers : Map < number , ( response : JSONRPCResultResponse | Error ) => void > = new Map ( ) ;
333- private _progressHandlers : Map < number , ProgressCallback > = new Map ( ) ;
329+ private _progressManager : ProgressManager = new ProgressManager ( ) ;
334330 private _timeoutInfo : Map < number , TimeoutInfo > = new Map ( ) ;
335331 private _pendingDebouncedNotifications = new Set < string > ( ) ;
336332
337- // Maps task IDs to progress tokens to keep handlers alive after CreateTaskResult
338- private _taskProgressTokens : Map < string , number > = new Map ( ) ;
339-
340333 private _taskStore ?: TaskStore ;
341334 private _taskMessageQueue ?: TaskMessageQueue ;
342335
@@ -639,8 +632,7 @@ export abstract class Protocol<SendRequestT extends Request, SendNotificationT e
639632 private _onclose ( ) : void {
640633 const responseHandlers = this . _responseHandlers ;
641634 this . _responseHandlers = new Map ( ) ;
642- this . _progressHandlers . clear ( ) ;
643- this . _taskProgressTokens . clear ( ) ;
635+ this . _progressManager . clear ( ) ;
644636 this . _pendingDebouncedNotifications . clear ( ) ;
645637
646638 const error = McpError . fromError ( ErrorCode . ConnectionClosed , 'Connection closed' ) ;
@@ -826,11 +818,10 @@ export abstract class Protocol<SendRequestT extends Request, SendNotificationT e
826818 }
827819
828820 private _onprogress ( notification : ProgressNotification ) : void {
829- const { progressToken, ... params } = notification . params ;
821+ const progressToken = notification . params . progressToken ;
830822 const messageId = Number ( progressToken ) ;
831823
832- const handler = this . _progressHandlers . get ( messageId ) ;
833- if ( ! handler ) {
824+ if ( ! this . _progressManager . hasHandler ( messageId ) ) {
834825 this . _onerror ( new Error ( `Received a progress notification for an unknown token: ${ JSON . stringify ( notification ) } ` ) ) ;
835826 return ;
836827 }
@@ -844,14 +835,14 @@ export abstract class Protocol<SendRequestT extends Request, SendNotificationT e
844835 } catch ( error ) {
845836 // Clean up if maxTotalTimeout was exceeded
846837 this . _responseHandlers . delete ( messageId ) ;
847- this . _progressHandlers . delete ( messageId ) ;
838+ this . _progressManager . removeHandler ( messageId ) ;
848839 this . _cleanupTimeout ( messageId ) ;
849840 responseHandler ( error as Error ) ;
850841 return ;
851842 }
852843 }
853844
854- handler ( params ) ;
845+ this . _progressManager . handleProgress ( notification ) ;
855846 }
856847
857848 private _onresponse ( response : JSONRPCResponse | JSONRPCErrorResponse ) : void {
@@ -887,13 +878,13 @@ export abstract class Protocol<SendRequestT extends Request, SendNotificationT e
887878 const task = result . task as Record < string , unknown > ;
888879 if ( typeof task . taskId === 'string' ) {
889880 isTaskResponse = true ;
890- this . _taskProgressTokens . set ( task . taskId , messageId ) ;
881+ this . _progressManager . linkTaskToProgressToken ( task . taskId , messageId ) ;
891882 }
892883 }
893884 }
894885
895886 if ( ! isTaskResponse ) {
896- this . _progressHandlers . delete ( messageId ) ;
887+ this . _progressManager . removeHandler ( messageId ) ;
897888 }
898889
899890 if ( isJSONRPCResultResponse ( response ) ) {
@@ -1116,7 +1107,7 @@ export abstract class Protocol<SendRequestT extends Request, SendNotificationT e
11161107 } ;
11171108
11181109 if ( options ?. onprogress ) {
1119- this . _progressHandlers . set ( messageId , options . onprogress ) ;
1110+ this . _progressManager . registerHandler ( messageId , options . onprogress ) ;
11201111 jsonrpcRequest . params = {
11211112 ...request . params ,
11221113 _meta : {
@@ -1147,7 +1138,7 @@ export abstract class Protocol<SendRequestT extends Request, SendNotificationT e
11471138
11481139 const cancel = ( reason : unknown ) => {
11491140 this . _responseHandlers . delete ( messageId ) ;
1150- this . _progressHandlers . delete ( messageId ) ;
1141+ this . _progressManager . removeHandler ( messageId ) ;
11511142 this . _cleanupTimeout ( messageId ) ;
11521143
11531144 this . _transport
@@ -1459,11 +1450,7 @@ export abstract class Protocol<SendRequestT extends Request, SendNotificationT e
14591450 * This should be called when a task reaches a terminal status.
14601451 */
14611452 private _cleanupTaskProgressHandler ( taskId : string ) : void {
1462- const progressToken = this . _taskProgressTokens . get ( taskId ) ;
1463- if ( progressToken !== undefined ) {
1464- this . _progressHandlers . delete ( progressToken ) ;
1465- this . _taskProgressTokens . delete ( taskId ) ;
1466- }
1453+ this . _progressManager . cleanupTaskProgressHandler ( taskId ) ;
14671454 }
14681455
14691456 /**
0 commit comments