From 7bf99cae8a3c0549fcedcf6dda6e8c323c5ff6b5 Mon Sep 17 00:00:00 2001 From: iyume Date: Mon, 19 May 2025 18:24:20 +0800 Subject: [PATCH 1/2] feat(messaging): Make sendMessage data parameter optional --- packages/messaging/src/generic.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/messaging/src/generic.ts b/packages/messaging/src/generic.ts index 41476fc..48b31e9 100644 --- a/packages/messaging/src/generic.ts +++ b/packages/messaging/src/generic.ts @@ -52,6 +52,12 @@ export interface GenericMessenger< * @param data The data to send with the message. * @param args Different messengers will have additional arguments to configure how a message gets sent. */ + sendMessage( + type: TType, + ...args: GetDataType extends undefined + ? [undefined?, ...TSendMessageArgs] + : never + ): Promise>; sendMessage( type: TType, data: GetDataType, From 4ba5691f212f46bedfacefd18c0305a3c25c8d4c Mon Sep 17 00:00:00 2001 From: Aaron Date: Sat, 14 Jun 2025 15:17:30 -0500 Subject: [PATCH 2/2] Update tests, add labels for better editor hints --- docs/content/index.md | 2 +- docs/content/messaging/api.md | 22 +++++++++++----------- packages/messaging/src/extension.test-d.ts | 21 +++++++++++++++++++-- packages/messaging/src/extension.test.ts | 2 +- packages/messaging/src/generic.ts | 12 ++++++------ packages/messaging/src/types.ts | 4 ++-- 6 files changed, 40 insertions(+), 23 deletions(-) diff --git a/docs/content/index.md b/docs/content/index.md index 065c114..34f3007 100644 --- a/docs/content/index.md +++ b/docs/content/index.md @@ -60,7 +60,7 @@ All Packages #title `@webext-core/messaging` #description - A simpler, type-safe API for sending and recieving messages. + A simpler, type-safe API for sending and receiving messages.

[Go to docs →](/messaging/installation) diff --git a/docs/content/messaging/api.md b/docs/content/messaging/api.md index 14d0a4d..19aa8a5 100644 --- a/docs/content/messaging/api.md +++ b/docs/content/messaging/api.md @@ -19,7 +19,7 @@ interface BaseMessagingConfig { Shared configuration between all the different messengers. -### Properties +### Properties - ***`logger?: Logger`*** (default: `console`)
The logger to use when logging messages. Set to `null` to disable logging. @@ -35,7 +35,7 @@ interface CustomEventMessage { Additional fields available on the `Message` from a `CustomEventMessenger`. -### Properties +### Properties - ***`event: CustomEvent`***
The event that was fired, resulting in the message being passed. @@ -153,7 +153,7 @@ interface ExtensionMessage { Additional fields available on the `Message` from an `ExtensionMessenger`. -### Properties +### Properties - ***`sender: Runtime.MessageSender`***
Information about where the message came from. See [`Runtime.MessageSender`](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/MessageSender). @@ -256,7 +256,7 @@ interface Logger { } ``` -Interface used to log text to the console when sending and recieving messages. +Interface used to log text to the console when sending and receiving messages. ## `MaybePromise` @@ -281,9 +281,9 @@ interface Message< } ``` -Contains information about the message recieved. +Contains information about the message received. -### Properties +### Properties - ***`id: number`***
A semi-unique, auto-incrementing number used to trace messages being sent. @@ -306,7 +306,7 @@ interface MessageSender { An object containing information about the script context that sent a message or request. -### Properties +### Properties - ***`tab?: Tabs.Tab`***
The $(ref:tabs.Tab) which opened the connection, if any. This property will only be present when the connection was opened from a tab (including content scripts), and only @@ -332,7 +332,7 @@ interface NamespaceMessagingConfig extends BaseMessagingConfig { } ``` -### Properties +### Properties - ***`namespace: string`***
A string used to ensure the messenger only sends messages to and listens for messages from other messengers of the same type, with the same namespace. @@ -354,7 +354,7 @@ Used to add a return type to a message in the protocol map. > Internally, this is just an object with random keys for the data and return types. -### Properties +### Properties - ***`BtVgCTPYZu: TData`***
Stores the data type. Randomly named so that it isn't accidentally implemented. @@ -392,7 +392,7 @@ interface SendMessageOptions { Options for sending a message to a specific tab/frame -### Properties +### Properties - ***`tabId: number`***
The tab to send a message to @@ -429,4 +429,4 @@ details. --- -_API reference generated by [`docs/generate-api-references.ts`](https://github.com/aklinker1/webext-core/blob/main/docs/generate-api-references.ts)_ \ No newline at end of file +_API reference generated by [`docs/generate-api-references.ts`](https://github.com/aklinker1/webext-core/blob/main/docs/generate-api-references.ts)_ diff --git a/packages/messaging/src/extension.test-d.ts b/packages/messaging/src/extension.test-d.ts index f548580..8add655 100644 --- a/packages/messaging/src/extension.test-d.ts +++ b/packages/messaging/src/extension.test-d.ts @@ -58,6 +58,11 @@ describe('Messenger Typing', () => { getStringLength: (data: string) => number; }>(); + // @ts-expect-error: Requires one parameter + sendMessage('getStringLength'); + sendMessage('getStringLength', 'test'); + sendMessage('getStringLength', 'test', 123); + expectTypeOf(sendMessage).parameter(0).toMatchTypeOf<'getStringLength'>(); expectTypeOf(sendMessage).parameter(1).toBeString(); expectTypeOf(sendMessage).returns.resolves.toBeNumber(); @@ -66,21 +71,33 @@ describe('Messenger Typing', () => { expectTypeOf(onMessage).parameter(1).returns.resolves.toBeNumber(); }); - it('should require passing undefined to sendMessage when there is no data', () => { + it('should accept passing undefined to sendMessage when there is no data', () => { const { sendMessage } = defineExtensionMessaging<{ ping: ProtocolWithReturn; }>(); + sendMessage('ping'); + sendMessage('ping', undefined); + // @ts-expect-error: It will still throw an error if you try to pass a target without sending `undefined` for the data. + sendMessage('ping', 123); + sendMessage('ping', undefined, 123); + expectTypeOf(sendMessage).parameter(0).toMatchTypeOf<'ping'>(); expectTypeOf(sendMessage).parameter(1).toBeUndefined(); expectTypeOf(sendMessage).parameter(2).toEqualTypeOf(); }); - it('should require passing undefined to sendMessage when there is no arguments in a function definition', () => { + it('should accept passing undefined to sendMessage when there is no arguments in a function definition', () => { const { sendMessage } = defineExtensionMessaging<{ ping(): 'pong'; }>(); + sendMessage('ping'); + sendMessage('ping', undefined); + // @ts-expect-error: It will still throw an error if you try to pass a target without sending `undefined` for the data. + sendMessage('ping', 123); + sendMessage('ping', undefined, 123); + expectTypeOf(sendMessage).parameter(0).toMatchTypeOf<'ping'>(); expectTypeOf(sendMessage).parameter(1).toBeUndefined(); expectTypeOf(sendMessage).parameter(2).toEqualTypeOf(); diff --git a/packages/messaging/src/extension.test.ts b/packages/messaging/src/extension.test.ts index 40a0591..18985c5 100644 --- a/packages/messaging/src/extension.test.ts +++ b/packages/messaging/src/extension.test.ts @@ -23,7 +23,7 @@ describe('Messaging Wrapper', () => { vi.restoreAllMocks(); }); - it('should send and recieve messages', async () => { + it('should send and receive messages', async () => { const { onMessage, sendMessage } = defineExtensionMessaging(); const input = 'test'; const expected = 4; diff --git a/packages/messaging/src/generic.ts b/packages/messaging/src/generic.ts index 48b31e9..1c5b113 100644 --- a/packages/messaging/src/generic.ts +++ b/packages/messaging/src/generic.ts @@ -55,7 +55,7 @@ export interface GenericMessenger< sendMessage( type: TType, ...args: GetDataType extends undefined - ? [undefined?, ...TSendMessageArgs] + ? [data?: undefined, ...args: TSendMessageArgs] : never ): Promise>; sendMessage( @@ -65,13 +65,13 @@ export interface GenericMessenger< ): Promise>; /** - * Trigger a callback when a message of the requested type is recieved. You cannot setup multiple + * Trigger a callback when a message of the requested type is received. You cannot setup multiple * listeners for the same message type in the same JS context. * * To remove the listener, call the returned message. * - * @param type The message type to listen for. Call `sendMessage` with the same type to triggern this listener. - * @param onReceived The callback executed when a message is recieved. + * @param type The message type to listen for. Call `sendMessage` with the same type to trigger this listener. + * @param onReceived The callback executed when a message is received. */ onMessage( type: TType, @@ -113,13 +113,13 @@ export function defineGenericMessanging< return { async sendMessage( type: TType, - data: TProtocolMap[TType], + data?: TProtocolMap[TType], ...args: TSendMessageArgs ): Promise { const _message: Message = { id: getNextId(), type: type, - data, + data: data as any, timestamp: Date.now(), }; const message = (await config.verifyMessageData?.(_message)) ?? _message; diff --git a/packages/messaging/src/types.ts b/packages/messaging/src/types.ts index 8ec0ce8..ff3dc3a 100644 --- a/packages/messaging/src/types.ts +++ b/packages/messaging/src/types.ts @@ -1,5 +1,5 @@ /** - * Interface used to log text to the console when sending and recieving messages. + * Interface used to log text to the console when sending and receiving messages. */ export interface Logger { debug(...args: any[]): void; @@ -95,7 +95,7 @@ export interface NamespaceMessagingConfig extends BaseMessagingConfig { } /** - * Contains information about the message recieved. + * Contains information about the message received. */ export interface Message< TProtocolMap extends Record,