From 084eaeae000f5ffa0bfebb965bfc43cc40f1f767 Mon Sep 17 00:00:00 2001 From: Harshit Jaiswal Date: Tue, 14 Jul 2026 23:07:24 +0530 Subject: [PATCH 1/2] fix(core): prevent debouncing notifications when relatedRequestId is 0 --- packages/core-internal/src/shared/protocol.ts | 5 ++++- .../core-internal/test/shared/protocol.test.ts | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/packages/core-internal/src/shared/protocol.ts b/packages/core-internal/src/shared/protocol.ts index ffab6e8df8..8563dc4b6a 100644 --- a/packages/core-internal/src/shared/protocol.ts +++ b/packages/core-internal/src/shared/protocol.ts @@ -1610,7 +1610,10 @@ export abstract class Protocol { const debouncedMethods = this._options?.debouncedNotificationMethods ?? []; // A notification can only be debounced if it's in the list AND it's "simple" // (i.e., has no parameters and no related request ID that could be lost). - const canDebounce = debouncedMethods.includes(notification.method) && !notification.params && !options?.relatedRequestId; + const canDebounce = + debouncedMethods.includes(notification.method) && + !notification.params && + options?.relatedRequestId === undefined; if (canDebounce) { // If a notification of this type is already scheduled, do nothing. diff --git a/packages/core-internal/test/shared/protocol.test.ts b/packages/core-internal/test/shared/protocol.test.ts index 2ecdc40adc..f8940fbb71 100644 --- a/packages/core-internal/test/shared/protocol.test.ts +++ b/packages/core-internal/test/shared/protocol.test.ts @@ -656,6 +656,22 @@ describe('protocol tests', () => { expect(sendSpy).toHaveBeenCalledWith(expect.any(Object), { relatedRequestId: 'req-2' }); }); + it('should NOT debounce a notification that has a relatedRequestId: 0', async () => { + // ARRANGE + protocol = new TestProtocolImpl({ debouncedNotificationMethods: ['test/debounced_with_options'] }); + await protocol.connect(transport); + + // ACT + void protocol.notification({ method: 'test/debounced_with_options' }, { relatedRequestId: 0 }); + void protocol.notification({ method: 'test/debounced_with_options' }, { relatedRequestId: 0 }); + await flushMicrotasks(); + + // ASSERT + expect(sendSpy).toHaveBeenCalledTimes(2); + expect(sendSpy).toHaveBeenNthCalledWith(1, expect.any(Object), { relatedRequestId: 0 }); + expect(sendSpy).toHaveBeenNthCalledWith(2, expect.any(Object), { relatedRequestId: 0 }); + }); + it('should clear pending debounced notifications on connection close', async () => { // ARRANGE protocol = new TestProtocolImpl({ debouncedNotificationMethods: ['test/debounced'] }); From fd2c01adc0fb668e0865f41ad2aa5925dc755433 Mon Sep 17 00:00:00 2001 From: Harshit Jaiswal Date: Tue, 14 Jul 2026 23:22:22 +0530 Subject: [PATCH 2/2] style(core): format protocol.ts with prettier --- packages/core-internal/src/shared/protocol.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/core-internal/src/shared/protocol.ts b/packages/core-internal/src/shared/protocol.ts index 8563dc4b6a..b3d1a061f2 100644 --- a/packages/core-internal/src/shared/protocol.ts +++ b/packages/core-internal/src/shared/protocol.ts @@ -1611,9 +1611,7 @@ export abstract class Protocol { // A notification can only be debounced if it's in the list AND it's "simple" // (i.e., has no parameters and no related request ID that could be lost). const canDebounce = - debouncedMethods.includes(notification.method) && - !notification.params && - options?.relatedRequestId === undefined; + debouncedMethods.includes(notification.method) && !notification.params && options?.relatedRequestId === undefined; if (canDebounce) { // If a notification of this type is already scheduled, do nothing.