@@ -28,7 +28,6 @@ import { parseSchema } from '../util/schema.js';
2828import type { NotificationOptions , Outbound , ProgressCallback , RequestEnv , RequestOptions } from './context.js' ;
2929import { DEFAULT_REQUEST_TIMEOUT_MSEC } from './context.js' ;
3030import type { Dispatcher } from './dispatcher.js' ;
31- import type { TaskManager } from './taskManager.js' ;
3231import type { AttachOptions , Transport } from './transport.js' ;
3332
3433type TimeoutInfo = {
@@ -48,13 +47,6 @@ export type StreamDriverOptions = {
4847 * {@linkcode MessageExtraInfo} (e.g. auth, http req).
4948 */
5049 buildEnv ?: ( extra : MessageExtraInfo | undefined , base : RequestEnv ) => RequestEnv ;
51- /**
52- * Optional {@linkcode TaskManager}. When provided, the driver calls its
53- * `processOutbound*` / `processInboundResponse` / `onClose` hooks at the
54- * request-correlation seam. Inbound task processing happens via the
55- * TaskManager's dispatch middleware (registered by the caller), not here.
56- */
57- taskManager ?: TaskManager ;
5850} ;
5951
6052/**
@@ -73,10 +65,18 @@ export class StreamDriver implements Outbound {
7365 private _pendingDebouncedNotifications = new Set < string > ( ) ;
7466 private _closed = false ;
7567 private _supportedProtocolVersions : string [ ] ;
76- private _taskManager ?: TaskManager ;
7768
7869 onclose ?: ( ) => void ;
7970 onerror ?: ( error : Error ) => void ;
71+ /**
72+ * Tap for every inbound response. Return `consumed: true` to claim it (suppresses the
73+ * matched-handler dispatch / unknown-id error). Return `preserveProgress: true` to keep
74+ * the progress handler registered after the matched handler runs. Set by the owner.
75+ */
76+ onresponse ?: (
77+ response : JSONRPCResponse | JSONRPCErrorResponse ,
78+ messageId : number
79+ ) => { consumed : boolean ; preserveProgress ?: boolean } ;
8080
8181 constructor (
8282 // eslint-disable-next-line @typescript-eslint/no-explicit-any -- driver is context-agnostic; subclass owns ContextT
@@ -85,7 +85,6 @@ export class StreamDriver implements Outbound {
8585 private _options : StreamDriverOptions = { }
8686 ) {
8787 this . _supportedProtocolVersions = _options . supportedProtocolVersions ?? SUPPORTED_PROTOCOL_VERSIONS ;
88- this . _taskManager = _options . taskManager ;
8988 }
9089
9190 /** {@linkcode Outbound.removeProgressHandler }. */
@@ -208,31 +207,19 @@ export class StreamDriver implements Outbound {
208207 options ?. resetTimeoutOnProgress ?? false
209208 ) ;
210209
211- let queued = false ;
212- if ( this . _taskManager ) {
213- const sideChannelResponse = ( resp : JSONRPCResultResponse | Error ) => {
214- const h = this . _responseHandlers . get ( messageId ) ;
215- if ( h ) h ( resp ) ;
216- else this . _onerror ( new Error ( `Response handler missing for side-channeled request ${ messageId } ` ) ) ;
217- } ;
218- try {
219- queued = this . _taskManager . processOutboundRequest ( jsonrpcRequest , options , messageId , sideChannelResponse , error => {
220- this . _progressHandlers . delete ( messageId ) ;
221- reject ( error ) ;
222- } ) . queued ;
223- } catch ( error ) {
210+ if ( options ?. intercept ) {
211+ const settle = ( r : JSONRPCResultResponse | Error ) => this . _responseHandlers . get ( messageId ) ?.( r ) ;
212+ const onError = ( e : unknown ) => {
224213 this . _progressHandlers . delete ( messageId ) ;
225- reject ( error ) ;
226- return ;
227- }
214+ reject ( e ) ;
215+ } ;
216+ if ( options . intercept ( jsonrpcRequest , messageId , settle , onError ) ) return ;
228217 }
229218
230- if ( ! queued ) {
231- this . pipe . send ( jsonrpcRequest , { relatedRequestId, resumptionToken, onresumptiontoken } ) . catch ( error => {
232- this . _progressHandlers . delete ( messageId ) ;
233- reject ( error ) ;
234- } ) ;
235- }
219+ this . pipe . send ( jsonrpcRequest , { relatedRequestId, resumptionToken, onresumptiontoken } ) . catch ( error => {
220+ this . _progressHandlers . delete ( messageId ) ;
221+ reject ( error ) ;
222+ } ) ;
236223 } ) . finally ( ( ) => {
237224 if ( onAbort ) options ?. signal ?. removeEventListener ( 'abort' , onAbort ) ;
238225 if ( cleanupId !== undefined ) {
@@ -246,9 +233,8 @@ export class StreamDriver implements Outbound {
246233 * Sends a notification over the pipe. Supports debouncing per the constructor option.
247234 */
248235 async notification ( notification : Notification , options ?: NotificationOptions ) : Promise < void > {
249- const taskResult = await this . _taskManager ?. processOutboundNotification ( notification , options ) ;
250- if ( taskResult ?. queued || this . _closed ) return ;
251- const jsonrpc : JSONRPCNotification = taskResult ?. jsonrpcNotification ?? {
236+ if ( this . _closed ) return ;
237+ const jsonrpc : JSONRPCNotification = {
252238 jsonrpc : '2.0' ,
253239 method : notification . method ,
254240 params : notification . params
@@ -345,19 +331,16 @@ export class StreamDriver implements Outbound {
345331
346332 private _onresponse ( response : JSONRPCResponse | JSONRPCErrorResponse ) : void {
347333 const messageId = Number ( response . id ) ;
348- const taskResult = this . _taskManager ?. processInboundResponse ( response , messageId ) ;
349- if ( taskResult ?. consumed ) return ;
350-
334+ const tap = this . onresponse ?.( response , messageId ) ;
335+ if ( tap ?. consumed ) return ;
351336 const handler = this . _responseHandlers . get ( messageId ) ;
352337 if ( handler === undefined ) {
353338 this . _onerror ( new Error ( `Received a response for an unknown message ID: ${ JSON . stringify ( response ) } ` ) ) ;
354339 return ;
355340 }
356341 this . _responseHandlers . delete ( messageId ) ;
357342 this . _cleanupTimeout ( messageId ) ;
358- if ( ! taskResult ?. preserveProgress ) {
359- this . _progressHandlers . delete ( messageId ) ;
360- }
343+ if ( ! tap ?. preserveProgress ) this . _progressHandlers . delete ( messageId ) ;
361344 if ( isJSONRPCResultResponse ( response ) ) {
362345 handler ( response ) ;
363346 } else {
@@ -370,7 +353,6 @@ export class StreamDriver implements Outbound {
370353 const responseHandlers = this . _responseHandlers ;
371354 this . _responseHandlers = new Map ( ) ;
372355 this . _progressHandlers . clear ( ) ;
373- this . _taskManager ?. onClose ( ) ;
374356 this . _pendingDebouncedNotifications . clear ( ) ;
375357 for ( const info of this . _timeoutInfo . values ( ) ) clearTimeout ( info . timeoutId ) ;
376358 this . _timeoutInfo . clear ( ) ;
@@ -439,12 +421,12 @@ export async function attachChannelTransport(
439421 const driver = new StreamDriver ( dispatcher , pipe , {
440422 supportedProtocolVersions : options ?. supportedProtocolVersions ,
441423 debouncedNotificationMethods : options ?. debouncedNotificationMethods ,
442- taskManager : options ?. taskManager ,
443424 buildEnv : options ?. buildEnv
444425 } ) ;
445- if ( options ?. onclose || options ?. onerror ) {
426+ if ( options ?. onclose || options ?. onerror || options ?. onresponse ) {
446427 driver . onclose = options . onclose ;
447428 driver . onerror = options . onerror ;
429+ driver . onresponse = options . onresponse ;
448430 }
449431 await driver . start ( ) ;
450432 return driver ;
0 commit comments