From c46030324418af461588ab57d7cd5fe8c3fcb058 Mon Sep 17 00:00:00 2001 From: Frederik Bolding Date: Fri, 24 Apr 2026 10:53:00 +0200 Subject: [PATCH 1/7] feat: Add subscribeOnce and waitUntil methods --- packages/messenger/src/Messenger.test.ts | 125 +++++++++++++++++++++++ packages/messenger/src/Messenger.ts | 30 ++++++ 2 files changed, 155 insertions(+) diff --git a/packages/messenger/src/Messenger.test.ts b/packages/messenger/src/Messenger.test.ts index ea37567b35a..71781b3b4e8 100644 --- a/packages/messenger/src/Messenger.test.ts +++ b/packages/messenger/src/Messenger.test.ts @@ -1010,6 +1010,131 @@ describe('Messenger', () => { }); }); + describe('subscribeOnce', () => { + it('unsubscribes automatically after receiving the first event', () => { + type MessageEvent = { + type: 'Fixture:message'; + payload: [string]; + }; + + const messenger = new Messenger<'Fixture', never, MessageEvent>({ + namespace: 'Fixture', + }); + + const handler = jest.fn(); + messenger.subscribeOnce('Fixture:message', handler); + messenger.publish('Fixture:message', 'foo'); + messenger.publish('Fixture:message', 'bar'); + + expect(handler).toHaveBeenCalledWith('foo'); + expect(handler).not.toHaveBeenCalledWith('bar'); + expect(handler.mock.calls).toHaveLength(1); + }); + + it('supports selectors', () => { + type MessageEvent = { + type: 'Fixture:message'; + payload: [{ value: string }]; + }; + + const messenger = new Messenger<'Fixture', never, MessageEvent>({ + namespace: 'Fixture', + }); + + const handler = jest.fn(); + messenger.subscribeOnce('Fixture:message', handler, ({ value }) => value); + messenger.publish('Fixture:message', { value: 'foo' }); + messenger.publish('Fixture:message', { value: 'bar' }); + + expect(handler).toHaveBeenCalledWith('foo'); + expect(handler).not.toHaveBeenCalledWith('bar'); + expect(handler.mock.calls).toHaveLength(1); + }); + + it('supports conditions', () => { + type MessageEvent = { + type: 'Fixture:message'; + payload: [{ value: string }]; + }; + + const messenger = new Messenger<'Fixture', never, MessageEvent>({ + namespace: 'Fixture', + }); + + const handler = jest.fn(); + messenger.subscribeOnce( + 'Fixture:message', + handler, + ({ value }) => value, + (value) => value === 'bar', + ); + messenger.publish('Fixture:message', { value: 'foo' }); + messenger.publish('Fixture:message', { value: 'bar' }); + + expect(handler).not.toHaveBeenCalledWith('foo'); + expect(handler).toHaveBeenCalledWith('bar'); + expect(handler.mock.calls).toHaveLength(1); + }); + }); + + describe('waitUntil', () => { + it('resolves the promise when the event fires', async () => { + type MessageEvent = { + type: 'Fixture:message'; + payload: [string]; + }; + + const messenger = new Messenger<'Fixture', never, MessageEvent>({ + namespace: 'Fixture', + }); + + const promise = messenger.waitUntil('Fixture:message'); + messenger.publish('Fixture:message', 'foo'); + + expect(await promise).toBe('foo'); + }); + + it('supports selectors', async () => { + type MessageEvent = { + type: 'Fixture:message'; + payload: [{ value: string }]; + }; + + const messenger = new Messenger<'Fixture', never, MessageEvent>({ + namespace: 'Fixture', + }); + + const promise = messenger.waitUntil( + 'Fixture:message', + ({ value }) => value, + ); + messenger.publish('Fixture:message', { value: 'foo' }); + + expect(await promise).toBe('foo'); + }); + + it('supports conditions', async () => { + type MessageEvent = { + type: 'Fixture:message'; + payload: [{ value: string }]; + }; + + const messenger = new Messenger<'Fixture', never, MessageEvent>({ + namespace: 'Fixture', + }); + + const promise = messenger.waitUntil( + 'Fixture:message', + ({ value }) => value, + (value) => value === 'bar', + ); + messenger.publish('Fixture:message', { value: 'foo' }); + messenger.publish('Fixture:message', { value: 'bar' }); + + expect(await promise).toBe('bar'); + }); + }); + describe('clearEventSubscriptions', () => { it('does not call subscriber after clearing event subscriptions', () => { type MessageEvent = { type: 'Fixture:message'; payload: [string] }; diff --git a/packages/messenger/src/Messenger.ts b/packages/messenger/src/Messenger.ts index 7b4db349933..db0caaea97e 100644 --- a/packages/messenger/src/Messenger.ts +++ b/packages/messenger/src/Messenger.ts @@ -656,6 +656,36 @@ export class Messenger< subscribers.set(handler, metadata); } + subscribeOnce( + eventType: EventType, + handler: + | ExtractEventHandler + | SelectorEventHandler, + selector?: SelectorFunction, + condition?: any, + ): void { + const internalHandler = (value) => { + if (condition && !condition(value)) { + return; + } + + handler(value); + this.unsubscribe(eventType, internalHandler); + }; + + this.subscribe(eventType, internalHandler, selector); + } + + waitUntil( + eventType: EventType, + selector?: SelectorFunction, + condition?: any, + ): Promise { + return new Promise((resolve) => { + this.subscribeOnce(eventType, resolve, selector, condition); + }); + } + /** * Unsubscribe from an event. * From c2bffe6e966bc8cbd79ba0314180dfb703acd1ec Mon Sep 17 00:00:00 2001 From: Frederik Bolding Date: Fri, 24 Apr 2026 11:26:47 +0200 Subject: [PATCH 2/7] Improve typing and docs --- packages/messenger/src/Messenger.test.ts | 10 +-- packages/messenger/src/Messenger.ts | 105 +++++++++++++++++++++-- 2 files changed, 102 insertions(+), 13 deletions(-) diff --git a/packages/messenger/src/Messenger.test.ts b/packages/messenger/src/Messenger.test.ts index 71781b3b4e8..ea958fd3e39 100644 --- a/packages/messenger/src/Messenger.test.ts +++ b/packages/messenger/src/Messenger.test.ts @@ -1026,8 +1026,8 @@ describe('Messenger', () => { messenger.publish('Fixture:message', 'foo'); messenger.publish('Fixture:message', 'bar'); - expect(handler).toHaveBeenCalledWith('foo'); - expect(handler).not.toHaveBeenCalledWith('bar'); + expect(handler).toHaveBeenCalledWith('foo', undefined); + expect(handler).not.toHaveBeenCalledWith('bar', 'foo'); expect(handler.mock.calls).toHaveLength(1); }); @@ -1046,8 +1046,8 @@ describe('Messenger', () => { messenger.publish('Fixture:message', { value: 'foo' }); messenger.publish('Fixture:message', { value: 'bar' }); - expect(handler).toHaveBeenCalledWith('foo'); - expect(handler).not.toHaveBeenCalledWith('bar'); + expect(handler).toHaveBeenCalledWith('foo', undefined); + expect(handler).not.toHaveBeenCalledWith('bar', 'foo'); expect(handler.mock.calls).toHaveLength(1); }); @@ -1072,7 +1072,7 @@ describe('Messenger', () => { messenger.publish('Fixture:message', { value: 'bar' }); expect(handler).not.toHaveBeenCalledWith('foo'); - expect(handler).toHaveBeenCalledWith('bar'); + expect(handler).toHaveBeenCalledWith('bar', 'foo'); expect(handler.mock.calls).toHaveLength(1); }); }); diff --git a/packages/messenger/src/Messenger.ts b/packages/messenger/src/Messenger.ts index db0caaea97e..18a4b9a9351 100644 --- a/packages/messenger/src/Messenger.ts +++ b/packages/messenger/src/Messenger.ts @@ -656,33 +656,122 @@ export class Messenger< subscribers.set(handler, metadata); } + /** + * Subscribe to an event, invoking the handler exactly once. + * + * Registers the given function as an event handler for the given event type + * and automatically unsubscribes after the first invocation. + * + * @param eventType - The event type. This is a unique identifier for this event. + * @param handler - The event handler. The type of the parameters for this event handler must + * match the type of the payload for this event type. + * @template EventType - A type union of Event type strings. + */ + subscribeOnce( + eventType: EventType, + handler: ExtractEventHandler, + ): void; + + /** + * Subscribe to an event, with a selector, invoking the handler exactly once. + * + * Registers the given handler function as an event handler for the given + * event type. When an event is published, its payload is first passed to the + * selector. The event handler is only called if the selector's return value + * differs from its last known return value. Additionally if the optional condition + * function is provided, it is checked whether it returns `true`. + * The handler is invoked at most once, after which the subscription is removed. + * + * @param eventType - The event type. This is a unique identifier for this event. + * @param handler - The event handler. The type of the parameters for this event + * handler must match the return type of the selector. + * @param selector - The selector function used to select relevant data from + * the event payload. The type of the parameters for this selector must match + * the type of the payload for this event type. + * @param condition - An optional predicate evaluated against the selector's return + * value. The handler is only invoked when this returns `true`. + * @template EventType - A type union of Event type strings. + * @template SelectorReturnValue - The selector return value. + */ + subscribeOnce( + eventType: EventType, + handler: SelectorEventHandler, + selector: SelectorFunction, + condition?: (value: SelectorReturnValue) => boolean, + ): void; + subscribeOnce( eventType: EventType, handler: | ExtractEventHandler | SelectorEventHandler, selector?: SelectorFunction, - condition?: any, + condition?: (value: SelectorReturnValue) => boolean, ): void { - const internalHandler = (value) => { + // Casting to selector specific types though this handles non-selector code paths as well. + const internalHandler: SelectorEventHandler = ( + value, + previousValue, + ) => { if (condition && !condition(value)) { return; } - - handler(value); + (handler as SelectorEventHandler)( + value, + previousValue, + ); this.unsubscribe(eventType, internalHandler); }; - this.subscribe(eventType, internalHandler, selector); + this.subscribe( + eventType, + internalHandler, + selector as SelectorFunction, + ); } + /** + * Return a promise that resolves the next time the given event is published. + * + * @param eventType - The event type. This is a unique identifier for this event. + * @template EventType - A type union of Event type strings. + * @returns A promise that resolves with the event payload's first argument. + */ + waitUntil( + eventType: EventType, + ): Promise[0]>; + + /** + * Return a promise that resolves the next time the selector's return value + * changes and, if provided, the condition function returns `true`. + * + * @param eventType - The event type. This is a unique identifier for this event. + * @param selector - The selector function used to select relevant data from + * the event payload. + * @param condition - An optional function which is executed with the selector's return + * value. The promise only resolves when this returns `true`. + * @template EventType - A type union of Event type strings. + * @template SelectorReturnValue - The selector return value. + * @returns A promise that resolves with the selector's return value. + */ + waitUntil( + eventType: EventType, + selector: SelectorFunction, + condition?: (value: SelectorReturnValue) => boolean, + ): Promise; + waitUntil( eventType: EventType, selector?: SelectorFunction, - condition?: any, - ): Promise { + condition?: (value: SelectorReturnValue) => boolean, + ): Promise[0]> { return new Promise((resolve) => { - this.subscribeOnce(eventType, resolve, selector, condition); + this.subscribeOnce( + eventType, + resolve as SelectorEventHandler, + selector as SelectorFunction, + condition, + ); }); } From f84cf14f328420ef734b9a072af5c00463b5cc1b Mon Sep 17 00:00:00 2001 From: Frederik Bolding Date: Fri, 24 Apr 2026 11:29:37 +0200 Subject: [PATCH 3/7] Add CHANGELOG entry --- packages/messenger/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/messenger/CHANGELOG.md b/packages/messenger/CHANGELOG.md index 83ce46c92c4..1b6913b4ba3 100644 --- a/packages/messenger/CHANGELOG.md +++ b/packages/messenger/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + + - Add `subscribeOnce` and `waitUntil` utility methods to `Messenger` ([#8575](https://github.com/MetaMask/core/pull/8575)) + ### Deprecated - Deprecate `generate-action-types` CLI tool and `messenger-generate-action-types` binary ([#8378](https://github.com/MetaMask/core/pull/8378)) From 580d0ac05154de5fd24546fe2bdd4ae1a755d04d Mon Sep 17 00:00:00 2001 From: Frederik Bolding Date: Fri, 24 Apr 2026 11:32:46 +0200 Subject: [PATCH 4/7] Fixup CHANGELOG --- packages/messenger/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/messenger/CHANGELOG.md b/packages/messenger/CHANGELOG.md index 1b6913b4ba3..6b868853ff2 100644 --- a/packages/messenger/CHANGELOG.md +++ b/packages/messenger/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - - Add `subscribeOnce` and `waitUntil` utility methods to `Messenger` ([#8575](https://github.com/MetaMask/core/pull/8575)) +- Add `subscribeOnce` and `waitUntil` utility methods to `Messenger` ([#8575](https://github.com/MetaMask/core/pull/8575)) ### Deprecated From 5907ef9b57940ce88870dd89e224cfe5ed5de484 Mon Sep 17 00:00:00 2001 From: Frederik Bolding Date: Fri, 24 Apr 2026 12:15:29 +0200 Subject: [PATCH 5/7] Use options bag --- packages/messenger/src/Messenger.test.ts | 79 +++++++++--- packages/messenger/src/Messenger.ts | 148 ++++++++++++++--------- 2 files changed, 151 insertions(+), 76 deletions(-) diff --git a/packages/messenger/src/Messenger.test.ts b/packages/messenger/src/Messenger.test.ts index ea958fd3e39..53aca5f1f9a 100644 --- a/packages/messenger/src/Messenger.test.ts +++ b/packages/messenger/src/Messenger.test.ts @@ -1026,8 +1026,8 @@ describe('Messenger', () => { messenger.publish('Fixture:message', 'foo'); messenger.publish('Fixture:message', 'bar'); - expect(handler).toHaveBeenCalledWith('foo', undefined); - expect(handler).not.toHaveBeenCalledWith('bar', 'foo'); + expect(handler).toHaveBeenCalledWith('foo'); + expect(handler).not.toHaveBeenCalledWith('bar'); expect(handler.mock.calls).toHaveLength(1); }); @@ -1042,7 +1042,9 @@ describe('Messenger', () => { }); const handler = jest.fn(); - messenger.subscribeOnce('Fixture:message', handler, ({ value }) => value); + messenger.subscribeOnce('Fixture:message', handler, { + selector: ({ value }) => value, + }); messenger.publish('Fixture:message', { value: 'foo' }); messenger.publish('Fixture:message', { value: 'bar' }); @@ -1051,7 +1053,29 @@ describe('Messenger', () => { expect(handler.mock.calls).toHaveLength(1); }); - it('supports conditions', () => { + it('supports conditions without a selector', () => { + type MessageEvent = { + type: 'Fixture:message'; + payload: [string]; + }; + + const messenger = new Messenger<'Fixture', never, MessageEvent>({ + namespace: 'Fixture', + }); + + const handler = jest.fn(); + messenger.subscribeOnce('Fixture:message', handler, { + condition: (value) => value === 'bar', + }); + messenger.publish('Fixture:message', 'foo'); + messenger.publish('Fixture:message', 'bar'); + + expect(handler).not.toHaveBeenCalledWith('foo'); + expect(handler).toHaveBeenCalledWith('bar'); + expect(handler.mock.calls).toHaveLength(1); + }); + + it('supports conditions with a selector', () => { type MessageEvent = { type: 'Fixture:message'; payload: [{ value: string }]; @@ -1062,12 +1086,10 @@ describe('Messenger', () => { }); const handler = jest.fn(); - messenger.subscribeOnce( - 'Fixture:message', - handler, - ({ value }) => value, - (value) => value === 'bar', - ); + messenger.subscribeOnce('Fixture:message', handler, { + selector: ({ value }) => value, + condition: (value) => value === 'bar', + }); messenger.publish('Fixture:message', { value: 'foo' }); messenger.publish('Fixture:message', { value: 'bar' }); @@ -1104,16 +1126,34 @@ describe('Messenger', () => { namespace: 'Fixture', }); - const promise = messenger.waitUntil( - 'Fixture:message', - ({ value }) => value, - ); + const promise = messenger.waitUntil('Fixture:message', { + selector: ({ value }) => value, + }); messenger.publish('Fixture:message', { value: 'foo' }); expect(await promise).toBe('foo'); }); - it('supports conditions', async () => { + it('supports conditions without a selector', async () => { + type MessageEvent = { + type: 'Fixture:message'; + payload: [string]; + }; + + const messenger = new Messenger<'Fixture', never, MessageEvent>({ + namespace: 'Fixture', + }); + + const promise = messenger.waitUntil('Fixture:message', { + condition: (value) => value === 'bar', + }); + messenger.publish('Fixture:message', 'foo'); + messenger.publish('Fixture:message', 'bar'); + + expect(await promise).toBe('bar'); + }); + + it('supports conditions with a selector', async () => { type MessageEvent = { type: 'Fixture:message'; payload: [{ value: string }]; @@ -1123,11 +1163,10 @@ describe('Messenger', () => { namespace: 'Fixture', }); - const promise = messenger.waitUntil( - 'Fixture:message', - ({ value }) => value, - (value) => value === 'bar', - ); + const promise = messenger.waitUntil('Fixture:message', { + selector: ({ value }) => value, + condition: (value) => value === 'bar', + }); messenger.publish('Fixture:message', { value: 'foo' }); messenger.publish('Fixture:message', { value: 'bar' }); diff --git a/packages/messenger/src/Messenger.ts b/packages/messenger/src/Messenger.ts index 18a4b9a9351..adecc839e28 100644 --- a/packages/messenger/src/Messenger.ts +++ b/packages/messenger/src/Messenger.ts @@ -656,22 +656,6 @@ export class Messenger< subscribers.set(handler, metadata); } - /** - * Subscribe to an event, invoking the handler exactly once. - * - * Registers the given function as an event handler for the given event type - * and automatically unsubscribes after the first invocation. - * - * @param eventType - The event type. This is a unique identifier for this event. - * @param handler - The event handler. The type of the parameters for this event handler must - * match the type of the payload for this event type. - * @template EventType - A type union of Event type strings. - */ - subscribeOnce( - eventType: EventType, - handler: ExtractEventHandler, - ): void; - /** * Subscribe to an event, with a selector, invoking the handler exactly once. * @@ -679,25 +663,55 @@ export class Messenger< * event type. When an event is published, its payload is first passed to the * selector. The event handler is only called if the selector's return value * differs from its last known return value. Additionally if the optional condition - * function is provided, it is checked whether it returns `true`. + * function is provided, it is checked whether it returns `true`. * The handler is invoked at most once, after which the subscription is removed. * * @param eventType - The event type. This is a unique identifier for this event. * @param handler - The event handler. The type of the parameters for this event * handler must match the return type of the selector. - * @param selector - The selector function used to select relevant data from - * the event payload. The type of the parameters for this selector must match - * the type of the payload for this event type. - * @param condition - An optional predicate evaluated against the selector's return - * value. The handler is only invoked when this returns `true`. + * @param options - Options bag. + * @param options.selector - The selector function used to select relevant data + * from the event payload. The type of the parameters for this selector must + * match the type of the payload for this event type. + * @param options.condition - An optional predicate evaluated against the + * selector's return value. The handler is only invoked when this returns `true`. * @template EventType - A type union of Event type strings. * @template SelectorReturnValue - The selector return value. */ subscribeOnce( eventType: EventType, handler: SelectorEventHandler, - selector: SelectorFunction, - condition?: (value: SelectorReturnValue) => boolean, + options: { + selector: SelectorFunction; + condition?: (value: SelectorReturnValue) => boolean; + }, + ): void; + + /** + * Subscribe to an event, invoking the handler exactly once. + * + * Registers the given function as an event handler for the given event type + * and automatically unsubscribes after the first invocation. + * + * If `options.condition` is provided, the handler is only invoked (and the + * subscription only removed) when the condition returns `true`. + * + * @param eventType - The event type. This is a unique identifier for this event. + * @param handler - The event handler. The type of the parameters for this event + * handler must match the type of the payload for this event type. + * @param options - Options bag. + * @param options.condition - A predicate evaluated against the event payload. + * The handler is only invoked when this returns `true`. + * @template EventType - A type union of Event type strings. + */ + subscribeOnce( + eventType: EventType, + handler: ExtractEventHandler, + options?: { + condition?: ( + ...payload: ExtractEventPayload + ) => boolean; + }, ): void; subscribeOnce( @@ -705,21 +719,23 @@ export class Messenger< handler: | ExtractEventHandler | SelectorEventHandler, - selector?: SelectorFunction, - condition?: (value: SelectorReturnValue) => boolean, + options?: { + selector?: SelectorFunction; + condition?: + | ((...payload: ExtractEventPayload) => boolean) + | ((value: SelectorReturnValue) => boolean); + }, ): void { - // Casting to selector specific types though this handles non-selector code paths as well. - const internalHandler: SelectorEventHandler = ( - value, - previousValue, - ) => { - if (condition && !condition(value)) { + const { selector, condition } = options ?? {}; + // Casting to unknown to handle both the code path where a selector is defined where it is omitted. + const internalHandler = (...args: unknown[]) => { + if ( + condition && + !(condition as (...args: unknown[]) => boolean)(...args) + ) { return; } - (handler as SelectorEventHandler)( - value, - previousValue, - ); + (handler as (...args: unknown[]) => void)(...args); this.unsubscribe(eventType, internalHandler); }; @@ -731,46 +747,66 @@ export class Messenger< } /** - * Return a promise that resolves the next time the given event is published. + * Return a promise that resolves the next time the selector's return value + * changes and, if provided, the `options.condition` predicate returns `true`. * * @param eventType - The event type. This is a unique identifier for this event. + * @param options - Options bag. + * @param options.selector - The selector function used to select relevant data + * from the event payload. + * @param options.condition - An optional predicate evaluated against the + * selector's return value. The promise only resolves when this returns `true`. * @template EventType - A type union of Event type strings. - * @returns A promise that resolves with the event payload's first argument. + * @template SelectorReturnValue - The selector return value. + * @returns A promise that resolves with the selector's return value. */ - waitUntil( + waitUntil( eventType: EventType, - ): Promise[0]>; + options: { + selector: SelectorFunction; + condition?: (value: SelectorReturnValue) => boolean; + }, + ): Promise; /** - * Return a promise that resolves the next time the selector's return value - * changes and, if provided, the condition function returns `true`. + * Return a promise that resolves the next time the given event is published. + * + * If `options.condition` is provided, the promise only resolves when the + * condition returns `true`. * * @param eventType - The event type. This is a unique identifier for this event. - * @param selector - The selector function used to select relevant data from - * the event payload. - * @param condition - An optional function which is executed with the selector's return - * value. The promise only resolves when this returns `true`. + * @param options - Options bag. + * @param options.condition - A predicate evaluated against the event payload. + * The promise only resolves when this returns `true`. * @template EventType - A type union of Event type strings. - * @template SelectorReturnValue - The selector return value. - * @returns A promise that resolves with the selector's return value. + * @returns A promise that resolves with the event payload's first argument. */ - waitUntil( + waitUntil( eventType: EventType, - selector: SelectorFunction, - condition?: (value: SelectorReturnValue) => boolean, - ): Promise; + options?: { + condition?: ( + ...payload: ExtractEventPayload + ) => boolean; + }, + ): Promise[0]>; waitUntil( eventType: EventType, - selector?: SelectorFunction, - condition?: (value: SelectorReturnValue) => boolean, + options?: { + selector?: SelectorFunction; + condition?: + | ((...payload: ExtractEventPayload) => boolean) + | ((value: SelectorReturnValue) => boolean); + }, ): Promise[0]> { return new Promise((resolve) => { this.subscribeOnce( eventType, resolve as SelectorEventHandler, - selector as SelectorFunction, - condition, + options as { + selector: SelectorFunction; + condition?: (value: SelectorReturnValue) => boolean; + }, ); }); } From b58d02b086f9b12c1e3ed01eccc59db8b9f24bdb Mon Sep 17 00:00:00 2001 From: Frederik Bolding Date: Fri, 24 Apr 2026 12:20:29 +0200 Subject: [PATCH 6/7] Add return type --- packages/messenger/src/Messenger.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/messenger/src/Messenger.ts b/packages/messenger/src/Messenger.ts index adecc839e28..480f58dfe3d 100644 --- a/packages/messenger/src/Messenger.ts +++ b/packages/messenger/src/Messenger.ts @@ -728,7 +728,7 @@ export class Messenger< ): void { const { selector, condition } = options ?? {}; // Casting to unknown to handle both the code path where a selector is defined where it is omitted. - const internalHandler = (...args: unknown[]) => { + const internalHandler = (...args: unknown[]): void => { if ( condition && !(condition as (...args: unknown[]) => boolean)(...args) From 620026118d605951c821ba8aa4b6413e089f46ff Mon Sep 17 00:00:00 2001 From: Frederik Bolding Date: Fri, 24 Apr 2026 12:20:43 +0200 Subject: [PATCH 7/7] Fix typo --- packages/messenger/src/Messenger.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/messenger/src/Messenger.ts b/packages/messenger/src/Messenger.ts index 480f58dfe3d..4739fdb1f59 100644 --- a/packages/messenger/src/Messenger.ts +++ b/packages/messenger/src/Messenger.ts @@ -727,7 +727,7 @@ export class Messenger< }, ): void { const { selector, condition } = options ?? {}; - // Casting to unknown to handle both the code path where a selector is defined where it is omitted. + // Casting to unknown to handle both the code path where a selector is defined and where it is omitted. const internalHandler = (...args: unknown[]): void => { if ( condition &&