Skip to content

Commit 187699b

Browse files
authored
refactor: move Connect, OnClose, OnOpen, OnError and OnMessage to @asyncapi/generator-components (#1717)
Co-authored-by: Adi-204 <adiboghawala@gmail.com>
1 parent 56b657f commit 187699b

File tree

26 files changed

+902
-296
lines changed

26 files changed

+902
-296
lines changed
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import { Text, render } from '@asyncapi/generator-react-sdk';
2+
import { OnOpen } from './OnOpen';
3+
import { OnMessage } from './OnMessage';
4+
import { OnError } from './OnError';
5+
import { OnClose } from './OnClose';
6+
7+
/**
8+
* @typedef {'python' | 'javascript' | 'dart'} SupportedLanguage
9+
* Supported programming languages for WebSocket connection method generation.
10+
*/
11+
12+
/**
13+
* Mapping of supported programming languages to their WebSocket connection method implementations.
14+
*
15+
* @type {Object.<SupportedLanguage, Function>}
16+
*/
17+
const websocketConnectMethod = {
18+
javascript: (onOpenMethod, onMessageMethod, onErrorMethod, onCloseMethod) => {
19+
return {
20+
connectMethod: `// Method to establish a WebSocket connection
21+
connect() {
22+
return new Promise((resolve, reject) => {
23+
this.websocket = new WebSocket(this.url);
24+
${onOpenMethod}
25+
${onMessageMethod}
26+
${onErrorMethod}
27+
${onCloseMethod}
28+
});
29+
}`
30+
};
31+
},
32+
python: (onOpenMethod, onMessageMethod, onErrorMethod, onCloseMethod) => {
33+
const onConnectMethod = `def connect(self):
34+
"""Establish the connection and start the run_forever loop in a background thread."""
35+
ssl_opts = {"ca_certs": certifi.where()}
36+
self.ws_app = websocket.WebSocketApp(
37+
self.url,
38+
on_open=self.on_open,
39+
on_message=self.on_message,
40+
on_error=self.on_error,
41+
on_close=self.on_close
42+
)
43+
# Run the WebSocketApp's run_forever in a separate thread with multithreading enabled.
44+
def run():
45+
46+
retry = 0
47+
max_retries = 5
48+
49+
while not self._stop_event.is_set() and retry < max_retries:
50+
try:
51+
retry += 1
52+
print("Starting WebSocket thread...")
53+
self.ws_app.run_forever(sslopt=ssl_opts)
54+
except Exception as e:
55+
print(f"Exception in WebSocket thread: {e}") # Print full error details
56+
57+
thread = threading.Thread(target=run, daemon=True)
58+
thread.start()`;
59+
return {
60+
connectMethod: `${onOpenMethod}
61+
${onMessageMethod}
62+
${onErrorMethod}
63+
${onCloseMethod}
64+
${onConnectMethod}`
65+
};
66+
},
67+
dart: (onMessageMethod, onErrorMethod, onCloseMethod, title) => {
68+
return {
69+
connectMethod: `/// Method to establish a WebSocket connection
70+
Future<void> connect() async {
71+
if (_channel != null) {
72+
print('Already connected to ${title} server');
73+
return;
74+
}
75+
try {
76+
final wsUrl = Uri.parse(_url);
77+
_channel = WebSocketChannel.connect(wsUrl);
78+
print('Connected to ${title} server');
79+
/// Listen to the incoming message stream
80+
_channel?.stream.listen(
81+
${onMessageMethod}
82+
${onErrorMethod}
83+
${onCloseMethod}
84+
);
85+
} catch (error) {
86+
print('Connection failed: $error');
87+
rethrow;
88+
}
89+
}`
90+
};
91+
}
92+
};
93+
94+
/**
95+
* Component that renders WebSocket connection method for the specified programming language.
96+
*
97+
* @param {Object} props - Component properties.
98+
* @param {SupportedLanguage} props.language - The programming language for which to generate connection code.
99+
* @param {string} props.title - The title of the WebSocket server.
100+
*/
101+
export function Connect({ language, title }) {
102+
const onOpenMethod = render(<OnOpen language={language} title={title} />);
103+
const onMessageMethod = render(<OnMessage language={language} />);
104+
const onErrorMethod = render(<OnError language={language} />);
105+
const onCloseMethod = render(<OnClose language={language} title={title} />);
106+
107+
const generateConnectCode = websocketConnectMethod[language];
108+
109+
let connectMethod;
110+
111+
if (language === 'dart') {
112+
const result = generateConnectCode(onMessageMethod, onErrorMethod, onCloseMethod, title);
113+
connectMethod = result.connectMethod;
114+
} else {
115+
const result = generateConnectCode(onOpenMethod, onMessageMethod, onErrorMethod, onCloseMethod);
116+
connectMethod = result.connectMethod;
117+
}
118+
119+
return (
120+
<Text newLines={2} indent={2}>
121+
{connectMethod}
122+
</Text>
123+
);
124+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { Text } from '@asyncapi/generator-react-sdk';
2+
3+
/**
4+
* @typedef {'python' | 'javascript' | 'dart' | 'java' } SupportedLanguage
5+
* Supported programming languages for WebSocket onClose handler generation.
6+
*/
7+
8+
/**
9+
* Mapping of supported programming languages to their WebSocket onClose event handler implementations.
10+
*
11+
* @type {Object.<SupportedLanguage, Function>}
12+
*/
13+
const websocketOnCloseMethod = {
14+
javascript: (title) => {
15+
return {
16+
onCloseMethod: `// On connection close
17+
this.websocket.onclose = () => {
18+
console.log('Disconnected from ${title} server');
19+
};`
20+
};
21+
},
22+
python: (title) => {
23+
return {
24+
onCloseMethod: `def on_close(self, ws, close_status_code, close_msg):
25+
print("Disconnected from ${title}", close_status_code, close_msg)`
26+
};
27+
},
28+
dart: (title) => {
29+
return {
30+
onCloseMethod: `onDone: () {
31+
_channel = null;
32+
print('Disconnected from ${title} server');
33+
},`
34+
};
35+
},
36+
java: {
37+
quarkus: (title) => {
38+
const onCloseMethod = `@OnClose
39+
public void onClose(CloseReason reason, WebSocketClientConnection connection) {
40+
int code = reason.getCode();
41+
LOG.info("Websocket disconnected from ${title} with Close code: " + code);
42+
}
43+
}`;
44+
return { onCloseMethod, indent: 2 };
45+
}
46+
}
47+
};
48+
49+
const resolveCloseConfig = (language, framework = '') => {
50+
const config = websocketOnCloseMethod[language];
51+
if (typeof config === 'function') {
52+
return config;
53+
}
54+
if (framework && typeof config[framework] === 'function') {
55+
return config[framework];
56+
}
57+
};
58+
59+
/**
60+
* Component that renders WebSocket onClose event handler for the specified programming language.
61+
*
62+
* @param {Object} props - Component properties.
63+
* @param {SupportedLanguage} props.language - The programming language for which to generate onClose handler code.
64+
* @param {string} [props.framework=''] - Optional framework variant (e.g., 'quarkus' for java).
65+
* @param {string} props.title - The title of the WebSocket server.
66+
*/
67+
export function OnClose({ language, framework = '', title }) {
68+
let onCloseMethod = '';
69+
let indent = 0;
70+
71+
if (websocketOnCloseMethod[language]) {
72+
const generateOnCloseCode = resolveCloseConfig(language, framework);
73+
const closeResult = generateOnCloseCode(title);
74+
onCloseMethod = closeResult.onCloseMethod;
75+
indent = closeResult.indent ?? 0;
76+
}
77+
78+
return (
79+
<Text indent={indent}>
80+
{onCloseMethod}
81+
</Text>
82+
);
83+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { Text } from '@asyncapi/generator-react-sdk';
2+
3+
/**
4+
* @typedef {'python' | 'javascript' | 'dart'} SupportedLanguage
5+
* Supported programming languages for WebSocket onError handler generation.
6+
*/
7+
8+
/**
9+
* Mapping of supported programming languages to their WebSocket onError event handler implementations.
10+
*
11+
* @type {Object.<SupportedLanguage, Function>}
12+
*/
13+
const websocketOnErrorMethod = {
14+
javascript: () => {
15+
return {
16+
onErrorMethod: `// On error first call custom error handlers, then default error behavior
17+
this.websocket.onerror = (error) => {
18+
if (this.errorHandlers.length > 0) {
19+
// Call custom error handlers
20+
this.errorHandlers.forEach(handler => handler(error));
21+
} else {
22+
// Default error behavior
23+
console.error('WebSocket Error:', error);
24+
}
25+
reject(error);
26+
};`
27+
};
28+
},
29+
python: () => {
30+
return {
31+
onErrorMethod: `def on_error(self, ws, error):
32+
print("WebSocket Error:", error)
33+
self.handle_error(error)`
34+
};
35+
},
36+
dart: () => {
37+
return {
38+
onErrorMethod: `onError: (error) {
39+
if (_errorHandlers.isNotEmpty) {
40+
for (var handler in _errorHandlers) {
41+
handler(error);
42+
}
43+
} else {
44+
print('WebSocket Error: $error');
45+
}
46+
},`
47+
};
48+
}
49+
};
50+
51+
/**
52+
* Component that renders WebSocket onError event handler for the specified programming language.
53+
*
54+
* @param {Object} props - Component properties.
55+
* @param {SupportedLanguage} props.language - The programming language for which to generate onError handler code.
56+
*/
57+
export function OnError({ language }) {
58+
let onErrorMethod = '';
59+
60+
if (websocketOnErrorMethod[language]) {
61+
const generateErrorCode = websocketOnErrorMethod[language];
62+
const errorResult = generateErrorCode();
63+
onErrorMethod = errorResult.onErrorMethod;
64+
}
65+
66+
return (
67+
<Text>
68+
{onErrorMethod}
69+
</Text>
70+
);
71+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { Text } from '@asyncapi/generator-react-sdk';
2+
3+
/**
4+
* @typedef {'python' | 'javascript' | 'dart'} SupportedLanguage
5+
* Supported programming languages for WebSocket onMessage handler generation.
6+
*/
7+
8+
/**
9+
* Mapping of supported programming languages to their WebSocket onMessage event handler implementations.
10+
*
11+
* @type {Object.<SupportedLanguage, Function>}
12+
*/
13+
const websocketOnMessageMethod = {
14+
javascript: () => {
15+
return {
16+
onMessageMethod: `// On receiving a message
17+
this.websocket.onmessage = (event) => {
18+
if (this.messageHandlers.length > 0) {
19+
// Call custom message handlers
20+
this.messageHandlers.forEach(handler => {
21+
if (typeof handler === 'function') {
22+
this.handleMessage(event.data, handler);
23+
}
24+
});
25+
} else {
26+
// Default message logging
27+
console.log('Message received:', event.data);
28+
}
29+
};`
30+
};
31+
},
32+
python: () => {
33+
return {
34+
onMessageMethod: `def on_message(self, ws, message):
35+
self.handle_message(message)`
36+
};
37+
},
38+
dart: () => {
39+
return {
40+
onMessageMethod: `(message) {
41+
if (_messageHandlers.isNotEmpty) {
42+
for (var handler in _messageHandlers) {
43+
_handleMessage(message, handler);
44+
}
45+
} else {
46+
print('Message received: $message');
47+
}
48+
},`
49+
};
50+
}
51+
};
52+
53+
/**
54+
* Component that renders WebSocket onMessage event handler for the specified programming language.
55+
*
56+
* @param {Object} props - Component properties.
57+
* @param {SupportedLanguage} props.language - The programming language for which to generate onMessage handler code.
58+
*/
59+
export function OnMessage({ language }) {
60+
let onMessageMethod = '';
61+
62+
if (websocketOnMessageMethod[language]) {
63+
const generateOnMessageCode = websocketOnMessageMethod[language];
64+
const messageResult = generateOnMessageCode();
65+
onMessageMethod = messageResult.onMessageMethod;
66+
}
67+
68+
return (
69+
<Text>
70+
{onMessageMethod}
71+
</Text>
72+
);
73+
}

0 commit comments

Comments
 (0)