diff --git a/packages/messenger/CHANGELOG.md b/packages/messenger/CHANGELOG.md index d73bc9a511..7d5e649555 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 `Messenger.getRegisteredActionTypes` method, which returns the action types the messenger can call directly ([#9271](https://github.com/MetaMask/core/pull/9271)) + ### Changed - Bump `@metamask/utils` from `^11.9.0` to `^11.11.0` ([#9074](https://github.com/MetaMask/core/pull/9074)) diff --git a/packages/messenger/src/Messenger.test.ts b/packages/messenger/src/Messenger.test.ts index c2c1f1615b..8018a8d665 100644 --- a/packages/messenger/src/Messenger.test.ts +++ b/packages/messenger/src/Messenger.test.ts @@ -345,6 +345,70 @@ describe('Messenger', () => { }); }); + describe('getRegisteredActionTypes', () => { + it('returns an empty array when no actions are registered', () => { + type PingAction = { type: 'Fixture:ping'; handler: () => void }; + const messenger = new Messenger<'Fixture', PingAction, never>({ + namespace: 'Fixture', + }); + + expect(messenger.getRegisteredActionTypes()).toStrictEqual([]); + }); + + it('returns the types of registered actions', () => { + type MessageAction = + | { type: 'Fixture:concat'; handler: (message: string) => void } + | { type: 'Fixture:reset'; handler: (initialMessage: string) => void }; + const messenger = new Messenger<'Fixture', MessageAction, never>({ + namespace: 'Fixture', + }); + + messenger.registerActionHandler('Fixture:concat', () => undefined); + messenger.registerActionHandler('Fixture:reset', () => undefined); + + expect(messenger.getRegisteredActionTypes()).toStrictEqual([ + 'Fixture:concat', + 'Fixture:reset', + ]); + }); + + it('no longer includes an action type after it is unregistered', () => { + type MessageAction = + | { type: 'Fixture:concat'; handler: (message: string) => void } + | { type: 'Fixture:reset'; handler: (initialMessage: string) => void }; + const messenger = new Messenger<'Fixture', MessageAction, never>({ + namespace: 'Fixture', + }); + + messenger.registerActionHandler('Fixture:concat', () => undefined); + messenger.registerActionHandler('Fixture:reset', () => undefined); + messenger.unregisterActionHandler('Fixture:concat'); + + expect(messenger.getRegisteredActionTypes()).toStrictEqual([ + 'Fixture:reset', + ]); + }); + + it('includes actions delegated in from another messenger', () => { + type CountAction = { + type: 'Source:count'; + handler: (increment: number) => void; + }; + const sourceMessenger = new Messenger<'Source', CountAction, never>({ + namespace: 'Source', + }); + const messenger = new Messenger<'Destination', CountAction, never>({ + namespace: 'Destination', + }); + sourceMessenger.registerActionHandler('Source:count', () => undefined); + sourceMessenger.delegate({ actions: ['Source:count'], messenger }); + + expect(messenger.getRegisteredActionTypes()).toStrictEqual([ + 'Source:count', + ]); + }); + }); + describe('publish and subscribe', () => { it('publishes event to subscriber', () => { type MessageEvent = { type: 'Fixture:message'; payload: [string] }; diff --git a/packages/messenger/src/Messenger.ts b/packages/messenger/src/Messenger.ts index 1f2c1d866d..8ca62c2de9 100644 --- a/packages/messenger/src/Messenger.ts +++ b/packages/messenger/src/Messenger.ts @@ -399,6 +399,22 @@ export class Messenger< } } + /** + * Get the types of all actions that this messenger can call directly. + * + * This includes actions registered on this messenger as well as actions that + * have been delegated into it from another messenger. It does not include + * actions this messenger has delegated out to other messengers. + * + * Note that this reflects the registrations on this specific messenger + * instance. + * + * @returns An array of every action type this messenger can call directly. + */ + getRegisteredActionTypes(): string[] { + return [...this.#actions.keys()]; + } + /** * Get the action handler for a given action type. *