This is an automated email from the ASF dual-hosted git repository.
tbonelee pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/zeppelin.git
The following commit(s) were added to refs/heads/master by this push:
new def2de1cc2 [ZEPPELIN-6446] Type message listener callbacks
def2de1cc2 is described below
commit def2de1cc24e9cfb80f3d22dd2232e8f73885cc0
Author: chaeyoung kim <[email protected]>
AuthorDate: Mon Oct 5 22:30:20 2026 +0900
[ZEPPELIN-6446] Type message listener callbacks
### What is this PR for?
The message listener decorator previously required `<at>ts-ignore` when
invoking decorated callbacks because its conditional callback type did not
align with the received payload.
This PR introduces a typed `MessageHandler<T>`, explicitly connects each
message operation `K` to `MessageReceiveDataTypeMap[K]`, and invokes the
callback without TypeScript suppression or broad `any` types. The existing test
now uses the actual `<at>MessageListener` decorator syntax to verify the typed
integration.
### What type of PR is it?
Refactoring
### Todos
* [x] Remove the `<at>ts-ignore` suppression
* [x] Preserve the relationship between message operations and payload types
* [x] Verify all existing message listeners compile
* [x] Add coverage using the actual decorator syntax
### What is the Jira issue?
https://issues.apache.org/jira/browse/ZEPPELIN-6446
### How should this be tested?
```bash
cd zeppelin-web-angular
npm run test:shell
npm run lint
npm run build:angular
```
Results:
* 167 shell unit tests passed
* Frontend lint passed with no errors
* Production Angular build passed
### Questions:
* Does the license files need to update? No.
* Is there breaking changes for older versions? No.
* Does this needs documentation? No.
Closes #5533 from chelsseeey/ZEPPELIN-6446-type-message-listener-callback.
Signed-off-by: ChanHo Lee <[email protected]>
---
.../src/app/core/message-listener/message-listener.spec.ts | 5 +----
.../src/app/core/message-listener/message-listener.ts | 13 +++++++------
2 files changed, 8 insertions(+), 10 deletions(-)
diff --git
a/zeppelin-web-angular/src/app/core/message-listener/message-listener.spec.ts
b/zeppelin-web-angular/src/app/core/message-listener/message-listener.spec.ts
index 7fd1778ae6..e88cc7ae56 100644
---
a/zeppelin-web-angular/src/app/core/message-listener/message-listener.spec.ts
+++
b/zeppelin-web-angular/src/app/core/message-listener/message-listener.spec.ts
@@ -70,15 +70,12 @@ describe('MessageListener', () => {
class TestComponent extends MessageListenersManager {
receivedData?: MessageReceiveDataTypeMap[OP.NOTE];
+ @MessageListener(OP.NOTE)
handleNote(data: MessageReceiveDataTypeMap[OP.NOTE]): void {
this.receivedData = data;
}
}
- const descriptor =
Object.getOwnPropertyDescriptor(TestComponent.prototype, 'handleNote')!;
-
- MessageListener(OP.NOTE)(TestComponent.prototype, 'handleNote',
descriptor);
-
const component = new TestComponent(messageService);
const data = {} as MessageReceiveDataTypeMap[OP.NOTE];
diff --git
a/zeppelin-web-angular/src/app/core/message-listener/message-listener.ts
b/zeppelin-web-angular/src/app/core/message-listener/message-listener.ts
index 93c6294700..acbba8f317 100644
--- a/zeppelin-web-angular/src/app/core/message-listener/message-listener.ts
+++ b/zeppelin-web-angular/src/app/core/message-listener/message-listener.ts
@@ -34,7 +34,7 @@ export class MessageListenersManager implements OnDestroy {
}
}
-type ListenerArgumentsType<T> = T extends undefined ? () => void : (data: T)
=> void;
+type MessageHandler<T> = (data: T) => void;
const createMessageListener = <K extends keyof MessageReceiveDataTypeMap, T>(
op: K,
@@ -43,9 +43,9 @@ const createMessageListener = <K extends keyof
MessageReceiveDataTypeMap, T>(
return function (
target: MessageListenersManager,
propertyKey: string,
- descriptor: TypedPropertyDescriptor<ListenerArgumentsType<T>>
+ descriptor: TypedPropertyDescriptor<MessageHandler<T>>
) {
- const oldValue = descriptor.value as ListenerArgumentsType<T>;
+ const oldValue = descriptor.value!;
const fn = function (this: MessageListenersManager) {
if (!this.__zeppelinMessageListeners$__) {
@@ -55,8 +55,7 @@ const createMessageListener = <K extends keyof
MessageReceiveDataTypeMap, T>(
this.__zeppelinMessageListeners$__.add(
receiver(this.messageService, op).subscribe(data => {
try {
- // @ts-ignore
- oldValue.apply(this, [data]);
+ oldValue.call(this, data);
} catch (error) {
console.error(`Failed to handle WebSocket OP ${String(op)}`,
error);
throw error;
@@ -76,7 +75,9 @@ const createMessageListener = <K extends keyof
MessageReceiveDataTypeMap, T>(
};
export const MessageListener = <K extends keyof MessageReceiveDataTypeMap>(op:
K) => {
- return createMessageListener(op, (messageService, targetOp) =>
messageService.receive(targetOp));
+ return createMessageListener<K, MessageReceiveDataTypeMap[K]>(op,
(messageService, targetOp) =>
+ messageService.receive(targetOp)
+ );
};
export const MessageEnvelopeListener = <K extends keyof
MessageReceiveDataTypeMap>(op: K) => {