@@ -15,83 +15,40 @@ class Serial extends EventTarget {
1515
1616 this . logHead = "[SERIAL]" ;
1717
18- // Initialize the available protocols
19- this . _webSerial = new WebSerial ( ) ;
20- this . _webBluetooth = new WebBluetooth ( ) ;
21- this . _webSocket = new Websocket ( ) ;
22- this . _virtual = new VirtualSerial ( ) ;
23-
24- // Update protocol map to use consistent naming
25- this . _protocolMap = {
26- webserial : this . _webSerial ,
27- webbluetooth : this . _webBluetooth ,
28- websocket : this . _webSocket ,
29- virtual : this . _virtual ,
30- } ;
18+ // Initialize protocols with metadata for easier lookup
19+ this . _protocols = [
20+ { name : "webserial" , instance : new WebSerial ( ) } ,
21+ { name : "webbluetooth" , instance : new WebBluetooth ( ) } ,
22+ { name : "websocket" , instance : new Websocket ( ) } ,
23+ { name : "virtual" , instance : new VirtualSerial ( ) } ,
24+ ] ;
3125
3226 // Forward events from all protocols to the Serial class
3327 this . _setupEventForwarding ( ) ;
3428 }
3529
36- // Add a getter method to safely access the protocol map
37- _getProtocolByType ( type ) {
38- if ( ! type ) {
39- return this . _protocol ;
40- }
41-
42- const protocol = this . _protocolMap [ type . toLowerCase ( ) ] ;
43-
44- if ( ! protocol ) {
45- console . warn ( `${ this . logHead } Unknown protocol type: ${ type } ` ) ;
46- }
47-
48- return protocol || null ;
49- }
50-
51- /**
52- * Get the protocol type as a string
53- * @param {Object } protocol - Protocol instance
54- * @returns {string } - Protocol type name
55- */
56- _getProtocolType ( protocol ) {
57- if ( protocol === this . _webSerial ) {
58- return "webserial" ;
59- }
60- if ( protocol === this . _webBluetooth ) {
61- return "webbluetooth" ;
62- }
63- if ( protocol === this . _webSocket ) {
64- return "websocket" ;
65- }
66- if ( protocol === this . _virtual ) {
67- return "virtual" ;
68- }
69- return "unknown" ;
70- }
71-
7230 /**
7331 * Set up event forwarding from all protocols to the Serial class
7432 */
7533 _setupEventForwarding ( ) {
76- const protocols = [ this . _webSerial , this . _webBluetooth , this . _webSocket , this . _virtual ] ;
7734 const events = [ "addedDevice" , "removedDevice" , "connect" , "disconnect" , "receive" ] ;
7835
79- protocols . forEach ( ( protocol ) => {
80- if ( protocol && typeof protocol . addEventListener === "function" ) {
36+ this . _protocols . forEach ( ( { name , instance } ) => {
37+ if ( typeof instance ? .addEventListener === "function" ) {
8138 events . forEach ( ( eventType ) => {
82- protocol . addEventListener ( eventType , ( event ) => {
39+ instance . addEventListener ( eventType , ( event ) => {
8340 let newDetail ;
8441 if ( event . type === "receive" ) {
8542 // For 'receive' events, we need to handle the data differently
8643 newDetail = {
8744 data : event . detail ,
88- protocolType : this . _getProtocolType ( protocol ) ,
45+ protocolType : name ,
8946 } ;
9047 } else {
9148 // For other events, we can use the detail directly
9249 newDetail = {
9350 ...event . detail ,
94- protocolType : this . _getProtocolType ( protocol ) ,
51+ protocolType : name ,
9552 } ;
9653 }
9754
@@ -111,47 +68,25 @@ class Serial extends EventTarget {
11168
11269 /**
11370 * Selects the appropriate protocol based on port path
114- * @param {string|null } portPath - Optional port path to determine protocol
115- * @param {boolean } forceDisconnect - Whether to force disconnect from current protocol
71+ * @param {string|null } portPath - Port path to determine protocol
11672 */
117- selectProtocol ( portPath = null , forceDisconnect = true ) {
73+ selectProtocol ( portPath ) {
11874 // Determine which protocol to use based on port path
119- let newProtocol ;
120-
121- if ( portPath ) {
122- // Select protocol based on port path
123- if ( portPath === "virtual" ) {
124- console . log ( `${ this . logHead } Using virtual protocol (based on port path)` ) ;
125- newProtocol = this . _virtual ;
126- } else if ( portPath === "manual" || / ^ ( t c p | w s ) : \/ \/ ( [ A - Z a - z 0 - 9 . - ] + ) (?: : ( \d + ) ) ? $ / . test ( portPath ) ) {
127- console . log ( `${ this . logHead } Using websocket protocol (based on port path)` ) ;
128- newProtocol = this . _webSocket ;
129- } else if ( portPath . startsWith ( "bluetooth" ) ) {
130- console . log ( `${ this . logHead } Using bluetooth protocol (based on port path: ${ portPath } )` ) ;
131- newProtocol = this . _webBluetooth ;
132- } else {
133- console . log ( `${ this . logHead } Using web serial protocol (based on port path: ${ portPath } )` ) ;
134- newProtocol = this . _webSerial ;
135- }
136- }
137-
138- // If we're switching to a different protocol
139- if ( this . _protocol !== newProtocol ) {
140- // Clean up previous protocol if exists
141- if ( this . _protocol && forceDisconnect ) {
142- // Disconnect if connected
143- if ( this . _protocol . connected ) {
144- console . log ( `${ this . logHead } Disconnecting from current protocol before switching` ) ;
145- this . _protocol . disconnect ( ) ;
146- }
147- }
148-
149- // Set new protocol
150- this . _protocol = newProtocol ;
151- console . log ( `${ this . logHead } Protocol switched successfully to:` , this . _protocol ) ;
75+ let protocol ;
76+
77+ // Select protocol based on port path. Default to webSerial for
78+ // typical serial device identifiers (e.g., COM1, /dev/ttyUSB0).
79+ if ( portPath === "virtual" ) {
80+ protocol = this . _protocols . find ( ( p ) => p . name === "virtual" ) ?. instance ;
81+ } else if ( portPath === "manual" || / ^ ( t c p | w s ) : \/ \/ ( [ A - Z a - z 0 - 9 . - ] + ) (?: : ( \d + ) ) ? $ / . test ( portPath ) ) {
82+ protocol = this . _protocols . find ( ( p ) => p . name === "websocket" ) ?. instance ;
83+ } else if ( portPath . startsWith ( "bluetooth" ) ) {
84+ protocol = this . _protocols . find ( ( p ) => p . name === "webbluetooth" ) ?. instance ;
85+ } else {
86+ protocol = this . _protocols . find ( ( p ) => p . name === "webserial" ) ?. instance ;
15287 }
15388
154- return this . _protocol ;
89+ return protocol ;
15590 }
15691
15792 /**
@@ -161,38 +96,16 @@ class Serial extends EventTarget {
16196 */
16297 async connect ( path , options , callback ) {
16398 // Select the appropriate protocol based directly on the port path
164- this . selectProtocol ( path ) ;
165-
166- if ( ! this . _protocol ) {
167- console . error ( `${ this . logHead } No valid protocol selected for connection` ) ;
168- return false ;
169- }
170-
171- // Check if already connected
172- if ( this . _protocol . connected ) {
173- console . warn ( `${ this . logHead } Protocol already connected, not connecting again` ) ;
174-
175- // If we're already connected to the requested port, return success
176- const connectedPort = this . _protocol . getConnectedPort ?. ( ) ;
177- if ( connectedPort && connectedPort . path === path ) {
178- console . log ( `${ this . logHead } Already connected to the requested port` ) ;
179- return true ;
180- }
181-
182- // If we're connected to a different port, disconnect first
183- console . log ( `${ this . logHead } Connected to a different port, disconnecting first` ) ;
184- const success = await this . disconnect ( ) ;
185- if ( ! success ) {
186- console . error ( `${ this . logHead } Failed to disconnect before reconnecting` ) ;
187- return false ;
188- }
189-
190- console . log ( `${ this . logHead } Reconnecting to new port:` , path ) ;
191- return this . _protocol . connect ( path , options , callback ) ;
99+ let result = false ;
100+ try {
101+ this . _protocol = this . selectProtocol ( path ) ;
102+ result = await this . _protocol . connect ( path , options , callback ) ;
103+ } catch ( error ) {
104+ console . error ( `${ this . logHead } Error during connection:` , error ) ;
105+ } finally {
106+ callback && callback ( result ) ;
107+ return result ;
192108 }
193-
194- console . log ( `${ this . logHead } Connecting to port:` , path , "with options:" , options ) ;
195- return this . _protocol . connect ( path , options , callback ) ;
196109 }
197110
198111 /**
@@ -201,34 +114,14 @@ class Serial extends EventTarget {
201114 * @returns {Promise<boolean> } - Promise resolving to true if disconnection was successful
202115 */
203116 async disconnect ( callback ) {
204- // Return immediately if no protocol is selected
205- if ( ! this . _protocol ) {
206- console . warn ( `${ this . logHead } No protocol selected, nothing to disconnect` ) ;
207- if ( callback ) callback ( false ) ;
208- return false ;
209- }
210-
117+ let result = false ;
211118 try {
212- // Handle case where we're already disconnected
213- if ( ! this . _protocol . connected ) {
214- console . log ( `${ this . logHead } Already disconnected, performing cleanup` ) ;
215- if ( callback ) {
216- callback ( true ) ;
217- }
218- return true ;
219- }
220-
221- // Create a promise that will resolve/reject based on the protocol's disconnect result
222- const success = await this . _protocol . disconnect ( ) ;
223-
224- if ( callback ) callback ( success ) ;
225- return success ;
119+ result = await this . _protocol ?. disconnect ( ) ;
226120 } catch ( error ) {
227121 console . error ( `${ this . logHead } Error during disconnect:` , error ) ;
228- if ( callback ) {
229- callback ( false ) ;
230- }
231- return Promise . resolve ( false ) ;
122+ } finally {
123+ callback && callback ( result ) ;
124+ return result ;
232125 }
233126 }
234127
@@ -253,7 +146,7 @@ class Serial extends EventTarget {
253146 async getDevices ( protocolType = null ) {
254147 try {
255148 // Get the appropriate protocol
256- const targetProtocol = this . _getProtocolByType ( protocolType ) ;
149+ const targetProtocol = this . _protocols . find ( ( p ) => p . name === protocolType ?. toLowerCase ( ) ) ?. instance ;
257150
258151 if ( ! targetProtocol ) {
259152 console . warn ( `${ this . logHead } No valid protocol for getting devices` ) ;
@@ -265,7 +158,7 @@ class Serial extends EventTarget {
265158 return [ ] ;
266159 }
267160
268- return targetProtocol . getDevices ( ) || [ ] ;
161+ return targetProtocol . getDevices ?. ( ) || [ ] ;
269162 } catch ( error ) {
270163 console . error ( `${ this . logHead } Error getting devices:` , error ) ;
271164 return [ ] ;
@@ -278,25 +171,15 @@ class Serial extends EventTarget {
278171 * @param {string } protocolType - Optional protocol type ('serial', 'bluetooth', etc.)
279172 * @returns {Promise<Object> } - Promise resolving to the selected device
280173 */
281- async requestPermissionDevice ( showAllDevices = false , protocolType = null ) {
174+ async requestPermissionDevice ( showAllDevices = false , protocolType ) {
175+ let result = false ;
282176 try {
283- // Get the appropriate protocol
284- const targetProtocol = this . _getProtocolByType ( protocolType ) ;
285-
286- if ( ! targetProtocol ) {
287- console . warn ( `${ this . logHead } No valid protocol for permission request` ) ;
288- return null ;
289- }
290-
291- if ( typeof targetProtocol . requestPermissionDevice !== "function" ) {
292- console . error ( `${ this . logHead } Selected protocol does not support permission requests` ) ;
293- return null ;
294- }
295-
296- return targetProtocol . requestPermissionDevice ( showAllDevices ) ;
177+ const targetProtocol = this . _protocols . find ( ( p ) => p . name === protocolType ?. toLowerCase ( ) ) ?. instance ;
178+ result = await targetProtocol . requestPermissionDevice ( showAllDevices ) ;
297179 } catch ( error ) {
298180 console . error ( `${ this . logHead } Error requesting device permission:` , error ) ;
299- return null ;
181+ } finally {
182+ return result ;
300183 }
301184 }
302185
@@ -311,7 +194,14 @@ class Serial extends EventTarget {
311194 * Get connection status
312195 */
313196 get connected ( ) {
314- return this . _protocol ? this . _protocol . connected : false ;
197+ return this . _protocol ?. connected || false ;
198+ }
199+
200+ /**
201+ * Get connectionId
202+ */
203+ get connectionId ( ) {
204+ return this . _protocol ?. connectionId || null ;
315205 }
316206}
317207
0 commit comments