tauri-plugin-serialplugin-api 2.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1114 @@
1
+ 'use strict';
2
+
3
+ var core = require('@tauri-apps/api/core');
4
+ var event = require('@tauri-apps/api/event');
5
+
6
+ /**
7
+ * Auto-reconnect manager for serial ports
8
+ * Handles automatic reconnection logic with configurable settings
9
+ */
10
+ class AutoReconnectManager {
11
+ constructor() {
12
+ this.enabled = false;
13
+ this.interval = 5000; // 5 seconds default
14
+ this.maxAttempts = 10; // 10 attempts default, null for infinite
15
+ this.currentAttempts = 0;
16
+ this.timer = null;
17
+ }
18
+ /**
19
+ * @description Enables auto-reconnect functionality
20
+ * @param {Object} options Auto-reconnect configuration options
21
+ * @param {number} [options.interval=5000] Reconnection interval in milliseconds
22
+ * @param {number | null} [options.maxAttempts=10] Maximum number of reconnection attempts (null for infinite)
23
+ * @param {Function} [options.onReconnect] Callback function called on each reconnection attempt
24
+ * @param {Function} options.reconnectFunction Function that performs the actual reconnection
25
+ * @returns {Promise<void>} A promise that resolves when auto-reconnect is enabled
26
+ */
27
+ async enable(options) {
28
+ if (this.enabled) {
29
+ console.warn('Auto-reconnect is already enabled');
30
+ return;
31
+ }
32
+ this.enabled = true;
33
+ this.interval = options.interval || 5000;
34
+ this.maxAttempts = options.maxAttempts === undefined ? 10 : options.maxAttempts;
35
+ this.currentAttempts = 0;
36
+ this.callback = options.onReconnect;
37
+ this.reconnectFunction = options.reconnectFunction;
38
+ console.log(`Auto-reconnect enabled: interval=${this.interval}ms, maxAttempts=${this.maxAttempts === null ? 'infinite' : this.maxAttempts}`);
39
+ }
40
+ /**
41
+ * @description Disables auto-reconnect functionality
42
+ * @returns {Promise<void>} A promise that resolves when auto-reconnect is disabled
43
+ */
44
+ async disable() {
45
+ if (!this.enabled) {
46
+ console.warn('Auto-reconnect is not enabled');
47
+ return;
48
+ }
49
+ this.enabled = false;
50
+ this.currentAttempts = 0;
51
+ this.callback = undefined;
52
+ this.reconnectFunction = undefined;
53
+ // Clear any pending reconnect timer
54
+ if (this.timer) {
55
+ clearTimeout(this.timer);
56
+ this.timer = null;
57
+ }
58
+ console.log('Auto-reconnect disabled');
59
+ }
60
+ /**
61
+ * @description Gets auto-reconnect status and configuration
62
+ * @returns {Object} Auto-reconnect information
63
+ */
64
+ getInfo() {
65
+ return {
66
+ enabled: this.enabled,
67
+ interval: this.interval,
68
+ maxAttempts: this.maxAttempts,
69
+ currentAttempts: this.currentAttempts,
70
+ hasCallback: !!this.callback
71
+ };
72
+ }
73
+ /**
74
+ * @description Starts the auto-reconnect process
75
+ * @returns {Promise<void>} A promise that resolves when auto-reconnect process starts
76
+ */
77
+ async start() {
78
+ if (!this.enabled || !this.reconnectFunction) {
79
+ return;
80
+ }
81
+ this.currentAttempts = 0;
82
+ await this.performAttempt();
83
+ }
84
+ /**
85
+ * @description Stops the auto-reconnect process (clears timer but keeps enabled)
86
+ * @returns {Promise<void>} A promise that resolves when auto-reconnect process stops
87
+ */
88
+ async stop() {
89
+ if (this.timer) {
90
+ clearTimeout(this.timer);
91
+ this.timer = null;
92
+ }
93
+ }
94
+ /**
95
+ * @description Resets the attempt counter
96
+ * @returns {Promise<void>} A promise that resolves when counter is reset
97
+ */
98
+ async reset() {
99
+ this.currentAttempts = 0;
100
+ }
101
+ /**
102
+ * @description Internal method to perform a single reconnection attempt
103
+ * @returns {Promise<void>} A promise that resolves when the attempt is complete
104
+ */
105
+ async performAttempt() {
106
+ if (!this.enabled || !this.reconnectFunction) {
107
+ return;
108
+ }
109
+ // Проверяем лимит ДО увеличения счётчика
110
+ if (this.maxAttempts !== null && this.currentAttempts >= this.maxAttempts) {
111
+ console.error(`Auto-reconnect failed after ${this.maxAttempts} attempts`);
112
+ if (this.callback) {
113
+ this.callback(false, this.currentAttempts);
114
+ }
115
+ return;
116
+ }
117
+ this.currentAttempts++;
118
+ console.log(`Auto-reconnect attempt ${this.currentAttempts}${this.maxAttempts !== null ? `/${this.maxAttempts}` : ''}`);
119
+ try {
120
+ const success = await this.reconnectFunction();
121
+ if (success) {
122
+ console.log('Auto-reconnect successful');
123
+ this.currentAttempts = 0; // Reset counter on success
124
+ if (this.callback) {
125
+ this.callback(true, this.currentAttempts);
126
+ }
127
+ }
128
+ else {
129
+ throw new Error('Reconnect function returned false');
130
+ }
131
+ }
132
+ catch (error) {
133
+ console.error(`Auto-reconnect attempt ${this.currentAttempts} failed:`, error);
134
+ if (this.callback) {
135
+ this.callback(false, this.currentAttempts);
136
+ }
137
+ // Schedule next attempt
138
+ if (this.enabled) {
139
+ this.timer = setTimeout(() => {
140
+ this.performAttempt();
141
+ }, this.interval);
142
+ }
143
+ }
144
+ }
145
+ isEnabled() {
146
+ return this.enabled;
147
+ }
148
+ getInterval() {
149
+ return this.interval;
150
+ }
151
+ getMaxAttempts() {
152
+ return this.maxAttempts;
153
+ }
154
+ getCurrentAttempts() {
155
+ return this.currentAttempts;
156
+ }
157
+ hasCallback() {
158
+ return !!this.callback;
159
+ }
160
+ }
161
+
162
+ class ListenerManager {
163
+ constructor() {
164
+ this.listeners = new Map();
165
+ this.listenerIdCounter = 0;
166
+ }
167
+ add(type, unlisten) {
168
+ const id = `${type}_${++this.listenerIdCounter}`;
169
+ this.listeners.set(id, { unlisten, type });
170
+ return () => {
171
+ try {
172
+ this.delete(id);
173
+ if (typeof unlisten === 'function') {
174
+ unlisten();
175
+ }
176
+ }
177
+ catch (error) {
178
+ console.warn(`Error in unlisten function for ${id}:`, error);
179
+ }
180
+ };
181
+ }
182
+ set(id, listener) {
183
+ this.listeners.set(id, listener);
184
+ return () => {
185
+ try {
186
+ this.delete(id);
187
+ if (typeof listener.unlisten === 'function') {
188
+ listener.unlisten();
189
+ }
190
+ }
191
+ catch (error) {
192
+ console.warn(`Error in unlisten function for ${id}:`, error);
193
+ }
194
+ };
195
+ }
196
+ delete(id) {
197
+ this.listeners.delete(id);
198
+ }
199
+ entries() {
200
+ return this.listeners.entries();
201
+ }
202
+ filterByType(type) {
203
+ return Array.from(this.listeners.entries()).filter(([_, l]) => l.type === type);
204
+ }
205
+ all() {
206
+ return Array.from(this.listeners.entries());
207
+ }
208
+ clear() {
209
+ this.listeners.clear();
210
+ }
211
+ getInfo() {
212
+ const all = this.all();
213
+ const data = all.filter(([_, l]) => l.type === 'data');
214
+ const disconnect = all.filter(([_, l]) => l.type === 'disconnect');
215
+ return {
216
+ total: all.length,
217
+ data: data.length,
218
+ disconnect: disconnect.length,
219
+ ids: all.map(([id]) => id)
220
+ };
221
+ }
222
+ get(id) {
223
+ return this.listeners.get(id);
224
+ }
225
+ }
226
+
227
+ exports.DataBits = void 0;
228
+ (function (DataBits) {
229
+ DataBits["Five"] = "Five";
230
+ DataBits["Six"] = "Six";
231
+ DataBits["Seven"] = "Seven";
232
+ DataBits["Eight"] = "Eight";
233
+ })(exports.DataBits || (exports.DataBits = {}));
234
+ exports.FlowControl = void 0;
235
+ (function (FlowControl) {
236
+ FlowControl["None"] = "None";
237
+ FlowControl["Software"] = "Software";
238
+ FlowControl["Hardware"] = "Hardware";
239
+ })(exports.FlowControl || (exports.FlowControl = {}));
240
+ exports.Parity = void 0;
241
+ (function (Parity) {
242
+ Parity["None"] = "None";
243
+ Parity["Odd"] = "Odd";
244
+ Parity["Even"] = "Even";
245
+ })(exports.Parity || (exports.Parity = {}));
246
+ exports.StopBits = void 0;
247
+ (function (StopBits) {
248
+ StopBits["One"] = "One";
249
+ StopBits["Two"] = "Two";
250
+ })(exports.StopBits || (exports.StopBits = {}));
251
+ exports.ClearBuffer = void 0;
252
+ (function (ClearBuffer) {
253
+ ClearBuffer["Input"] = "Input";
254
+ ClearBuffer["Output"] = "Output";
255
+ ClearBuffer["All"] = "All";
256
+ })(exports.ClearBuffer || (exports.ClearBuffer = {}));
257
+ class SerialPort {
258
+ constructor(options) {
259
+ this.listeners = new ListenerManager();
260
+ this.autoReconnectManager = new AutoReconnectManager();
261
+ this.isOpen = false;
262
+ this.encoding = options.encoding || 'utf-8';
263
+ this.options = {
264
+ path: options.path,
265
+ baudRate: options.baudRate,
266
+ dataBits: options.dataBits || exports.DataBits.Eight,
267
+ flowControl: options.flowControl || exports.FlowControl.None,
268
+ parity: options.parity || exports.Parity.None,
269
+ stopBits: options.stopBits || exports.StopBits.One,
270
+ size: options.size || 1024,
271
+ timeout: options.timeout || 200,
272
+ };
273
+ this.size = options.size || 1024;
274
+ }
275
+ /**
276
+ * @description Lists all available serial ports
277
+ * @returns {Promise<{ [key: string]: PortInfo }>} A promise that resolves to a map of port names to port information
278
+ */
279
+ static async available_ports() {
280
+ try {
281
+ const result = await core.invoke('plugin:serialplugin|available_ports');
282
+ return Promise.resolve(result);
283
+ }
284
+ catch (error) {
285
+ return Promise.reject(error);
286
+ }
287
+ }
288
+ /**
289
+ * @description Lists all available serial ports using platform-specific commands
290
+ * @returns {Promise<{ [key: string]: PortInfo }>} A promise that resolves to a map of port names to port information
291
+ */
292
+ static async available_ports_direct() {
293
+ try {
294
+ const result = await core.invoke('plugin:serialplugin|available_ports_direct');
295
+ return Promise.resolve(result);
296
+ }
297
+ catch (error) {
298
+ return Promise.reject(error);
299
+ }
300
+ }
301
+ /**
302
+ * @description Lists all managed serial ports (ports that are currently open and managed by the application).
303
+ * @returns {Promise<string[]>} A promise that resolves to an array of port paths (names).
304
+ */
305
+ static async managed_ports() {
306
+ try {
307
+ const result = await core.invoke('plugin:serialplugin|managed_ports');
308
+ return Promise.resolve(result);
309
+ }
310
+ catch (error) {
311
+ return Promise.reject(error);
312
+ }
313
+ }
314
+ /**
315
+ * @description Forcefully closes a specific serial port
316
+ * @param {string} path The path of the serial port to close
317
+ * @returns {Promise<void>} A promise that resolves when the port is closed
318
+ */
319
+ static async forceClose(path) {
320
+ return await core.invoke('plugin:serialplugin|force_close', { path });
321
+ }
322
+ /**
323
+ * @description Closes all open serial ports
324
+ * @returns {Promise<void>} A promise that resolves when all ports are closed
325
+ */
326
+ static async closeAll() {
327
+ return await core.invoke('plugin:serialplugin|close_all');
328
+ }
329
+ /**
330
+ * @description Gets the full serial number for a specific port
331
+ * On Windows, this can fix truncated serial numbers (e.g., "B4" → "B4:3D:4D:B1:5A:C8" for ESP32 devices)
332
+ * @param {string} path The port path (e.g., "COM3", "/dev/ttyUSB0")
333
+ * @returns {Promise<string>} A promise that resolves to the full serial number, or "Unknown" if not found
334
+ */
335
+ static async get_full_serial_number(path) {
336
+ try {
337
+ const result = await core.invoke('plugin:serialplugin|get_full_serial_number', { path });
338
+ return Promise.resolve(result);
339
+ }
340
+ catch (error) {
341
+ return Promise.reject(error);
342
+ }
343
+ }
344
+ /**
345
+ * @description Cancels listening for serial port data (does not affect disconnect listeners)
346
+ * @returns {Promise<void>} A promise that resolves when listening is cancelled
347
+ */
348
+ async cancelListen() {
349
+ try {
350
+ // Cancel only data listeners - disconnect listeners remain active
351
+ const dataListeners = this.listeners.filterByType('data');
352
+ for (const [id, listener] of dataListeners) {
353
+ try {
354
+ if (typeof listener.unlisten === 'function') {
355
+ listener.unlisten();
356
+ }
357
+ }
358
+ catch (error) {
359
+ console.warn(`Error unlistening data listener ${id}:`, error);
360
+ }
361
+ // Remove from map regardless of success/failure
362
+ this.listeners.delete(id);
363
+ }
364
+ return;
365
+ }
366
+ catch (error) {
367
+ return Promise.reject('Failed to cancel serial monitoring: ' + error);
368
+ }
369
+ }
370
+ /**
371
+ * @description Cancels all listeners (both data and disconnect listeners)
372
+ * @returns {Promise<void>} A promise that resolves when all listeners are cancelled
373
+ */
374
+ async cancelAllListeners() {
375
+ try {
376
+ const allListeners = this.listeners.all();
377
+ for (const [id, listener] of allListeners) {
378
+ try {
379
+ if (typeof listener.unlisten === 'function') {
380
+ listener.unlisten();
381
+ }
382
+ }
383
+ catch (error) {
384
+ console.warn(`Error unlistening listener ${id}:`, error);
385
+ }
386
+ // Remove from map regardless of success/failure
387
+ this.listeners.delete(id);
388
+ }
389
+ return;
390
+ }
391
+ catch (error) {
392
+ return Promise.reject('Failed to cancel all listeners: ' + error);
393
+ }
394
+ }
395
+ /**
396
+ * @description Gets information about active listeners (for debugging)
397
+ * @returns {Object} Information about active listeners
398
+ */
399
+ getListenersInfo() {
400
+ return this.listeners.getInfo();
401
+ }
402
+ /**
403
+ * @description Cancels reading data from the serial port
404
+ * @returns {Promise<void>} A promise that resolves when reading is cancelled
405
+ */
406
+ async cancelRead() {
407
+ try {
408
+ await core.invoke('plugin:serialplugin|cancel_read', {
409
+ path: this.options.path,
410
+ });
411
+ }
412
+ catch (error) {
413
+ return Promise.reject(error instanceof Error ? error : new Error(String(error)));
414
+ }
415
+ }
416
+ /**
417
+ * @description Changes the serial port configuration
418
+ * @param {object} options Configuration options
419
+ * @param {string} [options.path] New port path
420
+ * @param {number} [options.baudRate] New baud rate
421
+ * @returns {Promise<void>} A promise that resolves when configuration is changed
422
+ */
423
+ async change(options) {
424
+ try {
425
+ let isOpened = false;
426
+ if (this.isOpen) {
427
+ isOpened = true;
428
+ await this.close();
429
+ }
430
+ if (options.path) {
431
+ this.options.path = options.path;
432
+ }
433
+ if (options.baudRate) {
434
+ this.options.baudRate = options.baudRate;
435
+ }
436
+ if (isOpened) {
437
+ await this.open();
438
+ }
439
+ return Promise.resolve();
440
+ }
441
+ catch (error) {
442
+ return Promise.reject(error);
443
+ }
444
+ }
445
+ /**
446
+ * @description Closes the currently open serial port
447
+ * @returns {Promise<void>} A promise that resolves when the port is closed
448
+ */
449
+ async close() {
450
+ try {
451
+ if (!this.isOpen) {
452
+ return;
453
+ }
454
+ // Stop auto-reconnect temporarily to prevent conflicts
455
+ const wasAutoReconnectEnabled = this.autoReconnectManager.isEnabled();
456
+ if (wasAutoReconnectEnabled) {
457
+ await this.autoReconnectManager.stop();
458
+ }
459
+ // First we cancel the reading
460
+ try {
461
+ await this.cancelRead();
462
+ }
463
+ catch (cancelReadError) {
464
+ console.warn('Error during cancelRead:', cancelReadError);
465
+ }
466
+ // Closing the port
467
+ let res = undefined;
468
+ try {
469
+ res = await core.invoke('plugin:serialplugin|close', {
470
+ path: this.options.path,
471
+ });
472
+ }
473
+ catch (closeError) {
474
+ console.warn('Error during port close:', closeError);
475
+ }
476
+ // Cancel all listeners
477
+ try {
478
+ await this.cancelAllListeners();
479
+ }
480
+ catch (cancelListenError) {
481
+ console.warn('Error during cancelAllListeners:', cancelListenError);
482
+ // Try to clear listeners manually as fallback
483
+ try {
484
+ this.listeners.clear();
485
+ }
486
+ catch (clearError) {
487
+ console.warn('Error during manual listener clear:', clearError);
488
+ }
489
+ }
490
+ this.isOpen = false;
491
+ return res;
492
+ }
493
+ catch (error) {
494
+ return Promise.reject(error);
495
+ }
496
+ }
497
+ /**
498
+ * @description Sets up a listener for port disconnection events
499
+ * @param {Function} fn Callback function to handle disconnection
500
+ * @returns {Promise<void>} A promise that resolves when the listener is set up
501
+ */
502
+ async disconnected(fn) {
503
+ let sub_path = this.options.path?.toString().replaceAll(".", "-").replaceAll("/", "-");
504
+ let checkEvent = `plugin-serialplugin-disconnected-${sub_path}`;
505
+ console.log('listen event: ' + checkEvent);
506
+ const unListenResult = await event.listen(checkEvent, () => {
507
+ try {
508
+ fn();
509
+ }
510
+ catch (error) {
511
+ console.error(error);
512
+ }
513
+ });
514
+ if (typeof unListenResult === 'function') {
515
+ this.listeners.add('disconnect', unListenResult);
516
+ }
517
+ else {
518
+ console.warn('disconnected() did not return a valid unlisten function');
519
+ }
520
+ }
521
+ /**
522
+ * @description Enables auto-reconnect functionality
523
+ * @param {Object} options Auto-reconnect configuration options
524
+ * @param {number} [options.interval=5000] Reconnection interval in milliseconds
525
+ * @param {number | null} [options.maxAttempts=10] Maximum number of reconnection attempts (null for infinite)
526
+ * @param {Function} [options.onReconnect] Callback function called on each reconnection attempt
527
+ * @returns {Promise<void>} A promise that resolves when auto-reconnect is enabled
528
+ */
529
+ async enableAutoReconnect(options = {}) {
530
+ try {
531
+ await this.autoReconnectManager.enable({
532
+ ...options,
533
+ reconnectFunction: async () => {
534
+ if (this.isOpen) {
535
+ return true;
536
+ }
537
+ try {
538
+ await this.open();
539
+ return true;
540
+ }
541
+ catch (error) {
542
+ return false;
543
+ }
544
+ }
545
+ });
546
+ // Set up disconnect listener that triggers auto-reconnect
547
+ await this.disconnected(async () => {
548
+ this.isOpen = false;
549
+ if (this.autoReconnectManager.isEnabled()) {
550
+ await this.autoReconnectManager.start();
551
+ }
552
+ });
553
+ }
554
+ catch (error) {
555
+ return Promise.reject(error);
556
+ }
557
+ }
558
+ /**
559
+ * @description Disables auto-reconnect functionality
560
+ * @returns {Promise<void>} A promise that resolves when auto-reconnect is disabled
561
+ */
562
+ async disableAutoReconnect() {
563
+ try {
564
+ await this.autoReconnectManager.disable();
565
+ }
566
+ catch (error) {
567
+ return Promise.reject(error);
568
+ }
569
+ }
570
+ /**
571
+ * @description Gets auto-reconnect status and configuration
572
+ * @returns {Object} Auto-reconnect information
573
+ */
574
+ getAutoReconnectInfo() {
575
+ return {
576
+ enabled: this.autoReconnectManager.isEnabled(),
577
+ interval: this.autoReconnectManager.getInterval(),
578
+ maxAttempts: this.autoReconnectManager.getMaxAttempts(),
579
+ currentAttempts: this.autoReconnectManager.getCurrentAttempts(),
580
+ hasCallback: this.autoReconnectManager.hasCallback(),
581
+ };
582
+ }
583
+ /**
584
+ * @description Manually triggers a reconnection attempt
585
+ * @returns {Promise<boolean>} A promise that resolves to true if reconnection was successful
586
+ */
587
+ async manualReconnect() {
588
+ try {
589
+ if (this.isOpen) {
590
+ console.log('Port is already open, no need to reconnect');
591
+ return true;
592
+ }
593
+ console.log('Manual reconnection attempt...');
594
+ await this.open();
595
+ console.log('Manual reconnection successful');
596
+ return true;
597
+ }
598
+ catch (error) {
599
+ console.error('Manual reconnection failed:', error);
600
+ return false;
601
+ }
602
+ }
603
+ /**
604
+ * @description Monitors serial port data
605
+ * @param {Function} fn Callback function to handle received data
606
+ * @param {boolean} [isDecode=true] Whether to decode the received data
607
+ * @returns {Promise<UnlistenFn>} A promise that resolves to an unlisten function
608
+ */
609
+ async listen(fn, isDecode = true) {
610
+ try {
611
+ if (!this.isOpen) {
612
+ return Promise.reject('Port is not open');
613
+ }
614
+ let sub_path = this.options.path?.toString().replaceAll(".", "-").replaceAll("/", "-");
615
+ let readEvent = `plugin-serialplugin-read-${sub_path}`;
616
+ console.log('listen event: ' + readEvent);
617
+ try {
618
+ const unListenResult = await event.listen(readEvent, ({ payload }) => {
619
+ try {
620
+ if (isDecode) {
621
+ const uint8Array = new Uint8Array(payload.data);
622
+ try {
623
+ const decoder = new TextDecoder(this.encoding);
624
+ const textData = decoder.decode(uint8Array);
625
+ fn(textData);
626
+ }
627
+ catch (error) {
628
+ console.error('Error converting to text with configured encoding:', error);
629
+ try {
630
+ const fallbackDecoder = new TextDecoder('utf-8');
631
+ const textData = fallbackDecoder.decode(uint8Array);
632
+ fn(textData);
633
+ }
634
+ catch (fallbackError) {
635
+ console.error('Fallback decoding also failed:', fallbackError);
636
+ fn(String.fromCharCode(...uint8Array));
637
+ }
638
+ }
639
+ }
640
+ else {
641
+ fn(new Uint8Array(payload.data));
642
+ }
643
+ }
644
+ catch (error) {
645
+ console.error(error);
646
+ }
647
+ });
648
+ if (typeof unListenResult === 'function') {
649
+ return this.listeners.add('data', unListenResult);
650
+ }
651
+ else {
652
+ console.warn('listen() did not return a valid unlisten function');
653
+ return Promise.reject('Failed to get unlisten function');
654
+ }
655
+ }
656
+ catch (listenError) {
657
+ console.error('Error setting up listener:', listenError);
658
+ throw listenError;
659
+ }
660
+ }
661
+ catch (error) {
662
+ return Promise.reject('Failed to monitor serial port data: ' + error);
663
+ }
664
+ }
665
+ /**
666
+ * @description Opens the serial port with current settings
667
+ * @returns {Promise<void>} A promise that resolves when the port is opened
668
+ */
669
+ async open() {
670
+ try {
671
+ if (!this.options.path) {
672
+ return Promise.reject(`path Can not be empty!`);
673
+ }
674
+ if (!this.options.baudRate) {
675
+ return Promise.reject(`baudRate Can not be empty!`);
676
+ }
677
+ if (this.isOpen) {
678
+ return;
679
+ }
680
+ const res = await core.invoke('plugin:serialplugin|open', {
681
+ path: this.options.path,
682
+ baudRate: this.options.baudRate,
683
+ dataBits: this.options.dataBits,
684
+ flowControl: this.options.flowControl,
685
+ parity: this.options.parity,
686
+ stopBits: this.options.stopBits,
687
+ timeout: this.options.timeout,
688
+ });
689
+ this.isOpen = true;
690
+ this.disconnected(() => {
691
+ this.isOpen = false;
692
+ }).catch(err => console.error(err));
693
+ return Promise.resolve(res);
694
+ }
695
+ catch (error) {
696
+ return Promise.reject(error);
697
+ }
698
+ }
699
+ /**
700
+ * Starts listening for data on the serial port
701
+ * The port will continuously monitor for incoming data and emit events
702
+ * @returns {Promise<void>} A promise that resolves when listening starts
703
+ * @throws {Error} If starting listener fails or port is not open
704
+ * @example
705
+ * const port = new SerialPort({ path: '/dev/ttyUSB0' });
706
+ * await port.startListening();
707
+ * // Listen for data events
708
+ * port.listen((data) => {
709
+ * console.log('listen', data)
710
+ * receivedData += data;
711
+ * });
712
+ */
713
+ async startListening() {
714
+ try {
715
+ await core.invoke('plugin:serialplugin|start_listening', {
716
+ path: this.options.path,
717
+ size: this.options.size,
718
+ timeout: this.options.timeout,
719
+ });
720
+ }
721
+ catch (error) {
722
+ return Promise.reject(error);
723
+ }
724
+ }
725
+ /**
726
+ * Stops listening for data on the serial port
727
+ * Cleans up event listeners and monitoring threads
728
+ * @returns {Promise<void>} A promise that resolves when listening stops
729
+ * @throws {Error} If stopping listener fails or port is not open
730
+ * @example
731
+ * await port.stopListening();
732
+ */
733
+ async stopListening() {
734
+ try {
735
+ await core.invoke('plugin:serialplugin|stop_listening', {
736
+ path: this.options.path,
737
+ });
738
+ }
739
+ catch (error) {
740
+ return Promise.reject(error);
741
+ }
742
+ }
743
+ /**
744
+ * @description Reads data from the serial port
745
+ * @param {ReadOptions} [options] Read options
746
+ * @returns {Promise<void>} A promise that resolves when data is read
747
+ */
748
+ async read(options) {
749
+ try {
750
+ if (!this.isOpen) {
751
+ return Promise.reject('Port is not open');
752
+ }
753
+ return await core.invoke('plugin:serialplugin|read', {
754
+ path: this.options.path,
755
+ timeout: options?.timeout || this.options.timeout,
756
+ size: options?.size || this.size,
757
+ });
758
+ }
759
+ catch (error) {
760
+ return Promise.reject(error);
761
+ }
762
+ }
763
+ /**
764
+ * @description Reads binary data from the serial port
765
+ * @param {ReadOptions} [options] Read options
766
+ * @returns {Promise<Uint8Array>} A promise that resolves with binary data
767
+ */
768
+ async readBinary(options) {
769
+ try {
770
+ const result = await core.invoke('plugin:serialplugin|read_binary', {
771
+ path: this.options.path,
772
+ timeout: options?.timeout || this.options.timeout,
773
+ size: options?.size || this.size,
774
+ });
775
+ return new Uint8Array(result);
776
+ }
777
+ catch (error) {
778
+ return Promise.reject(error);
779
+ }
780
+ }
781
+ /**
782
+ * @description Sets the baud rate of the serial port
783
+ * @param {number} value The new baud rate
784
+ * @returns {Promise<void>} A promise that resolves when baud rate is set
785
+ */
786
+ async setBaudRate(value) {
787
+ try {
788
+ return await core.invoke('plugin:serialplugin|set_baud_rate', {
789
+ path: this.options.path,
790
+ baudRate: value
791
+ });
792
+ }
793
+ catch (error) {
794
+ return Promise.reject(error);
795
+ }
796
+ }
797
+ /**
798
+ * @description Sets the data bits configuration
799
+ * @param {DataBits} value The new data bits setting
800
+ * @returns {Promise<void>} A promise that resolves when data bits are set
801
+ */
802
+ async setDataBits(value) {
803
+ try {
804
+ return await core.invoke('plugin:serialplugin|set_data_bits', {
805
+ path: this.options.path,
806
+ dataBits: value
807
+ });
808
+ }
809
+ catch (error) {
810
+ return Promise.reject(error);
811
+ }
812
+ }
813
+ /**
814
+ * @description Sets the flow control mode
815
+ * @param {FlowControl} value The new flow control setting
816
+ * @returns {Promise<void>} A promise that resolves when flow control is set
817
+ */
818
+ async setFlowControl(value) {
819
+ try {
820
+ return await core.invoke('plugin:serialplugin|set_flow_control', {
821
+ path: this.options.path,
822
+ flowControl: value
823
+ });
824
+ }
825
+ catch (error) {
826
+ return Promise.reject(error);
827
+ }
828
+ }
829
+ /**
830
+ * @description Sets the parity checking mode
831
+ * @param {Parity} value The new parity setting
832
+ * @returns {Promise<void>} A promise that resolves when parity is set
833
+ */
834
+ async setParity(value) {
835
+ try {
836
+ return await core.invoke('plugin:serialplugin|set_parity', {
837
+ path: this.options.path,
838
+ parity: value
839
+ });
840
+ }
841
+ catch (error) {
842
+ return Promise.reject(error);
843
+ }
844
+ }
845
+ /**
846
+ * @description Sets the number of stop bits
847
+ * @param {StopBits} value The new stop bits setting
848
+ * @returns {Promise<void>} A promise that resolves when stop bits are set
849
+ */
850
+ async setStopBits(value) {
851
+ try {
852
+ return await core.invoke('plugin:serialplugin|set_stop_bits', {
853
+ path: this.options.path,
854
+ stopBits: value
855
+ });
856
+ }
857
+ catch (error) {
858
+ return Promise.reject(error);
859
+ }
860
+ }
861
+ /**
862
+ * @description Sets the timeout duration
863
+ * @param {number} value The new timeout in milliseconds
864
+ * @returns {Promise<void>} A promise that resolves when timeout is set
865
+ */
866
+ async setTimeout(value) {
867
+ try {
868
+ return await core.invoke('plugin:serialplugin|set_timeout', {
869
+ path: this.options.path,
870
+ timeout: value
871
+ });
872
+ }
873
+ catch (error) {
874
+ return Promise.reject(error);
875
+ }
876
+ }
877
+ /**
878
+ * @description Sets the RTS (Request To Send) control signal
879
+ * @param {boolean} value The signal level to set
880
+ * @returns {Promise<void>} A promise that resolves when RTS is set
881
+ */
882
+ async setRequestToSend(value) {
883
+ try {
884
+ return await core.invoke('plugin:serialplugin|write_request_to_send', {
885
+ path: this.options.path,
886
+ level: value
887
+ });
888
+ }
889
+ catch (error) {
890
+ return Promise.reject(error);
891
+ }
892
+ }
893
+ /**
894
+ * @description Sets the DTR (Data Terminal Ready) control signal
895
+ * @param {boolean} value The signal level to set
896
+ * @returns {Promise<void>} A promise that resolves when DTR is set
897
+ */
898
+ async setDataTerminalReady(value) {
899
+ try {
900
+ return await core.invoke('plugin:serialplugin|write_data_terminal_ready', {
901
+ path: this.options.path,
902
+ level: value
903
+ });
904
+ }
905
+ catch (error) {
906
+ return Promise.reject(error);
907
+ }
908
+ }
909
+ /**
910
+ * @description Writes the RTS (Request To Send) control signal
911
+ * @param {boolean} level The signal level to set
912
+ * @returns {Promise<void>} A promise that resolves when RTS is set
913
+ */
914
+ async writeRequestToSend(level) {
915
+ try {
916
+ return await core.invoke('plugin:serialplugin|write_request_to_send', {
917
+ path: this.options.path,
918
+ level: level
919
+ });
920
+ }
921
+ catch (error) {
922
+ return Promise.reject(error);
923
+ }
924
+ }
925
+ /**
926
+ * @description Writes the DTR (Data Terminal Ready) control signal
927
+ * @param {boolean} level The signal level to set
928
+ * @returns {Promise<void>} A promise that resolves when DTR is set
929
+ */
930
+ async writeDataTerminalReady(level) {
931
+ try {
932
+ return await core.invoke('plugin:serialplugin|write_data_terminal_ready', {
933
+ path: this.options.path,
934
+ level: level
935
+ });
936
+ }
937
+ catch (error) {
938
+ return Promise.reject(error);
939
+ }
940
+ }
941
+ /**
942
+ * @description Reads the CTS (Clear To Send) control signal state
943
+ * @returns {Promise<boolean>} A promise that resolves to the CTS state
944
+ */
945
+ async readClearToSend() {
946
+ try {
947
+ return await core.invoke('plugin:serialplugin|read_clear_to_send', {
948
+ path: this.options.path
949
+ });
950
+ }
951
+ catch (error) {
952
+ return Promise.reject(error);
953
+ }
954
+ }
955
+ /**
956
+ * @description Reads the DSR (Data Set Ready) control signal state
957
+ * @returns {Promise<boolean>} A promise that resolves to the DSR state
958
+ */
959
+ async readDataSetReady() {
960
+ try {
961
+ return await core.invoke('plugin:serialplugin|read_data_set_ready', {
962
+ path: this.options.path
963
+ });
964
+ }
965
+ catch (error) {
966
+ return Promise.reject(error);
967
+ }
968
+ }
969
+ /**
970
+ * @description Reads the RI (Ring Indicator) control signal state
971
+ * @returns {Promise<boolean>} A promise that resolves to the RI state
972
+ */
973
+ async readRingIndicator() {
974
+ try {
975
+ return await core.invoke('plugin:serialplugin|read_ring_indicator', {
976
+ path: this.options.path
977
+ });
978
+ }
979
+ catch (error) {
980
+ return Promise.reject(error);
981
+ }
982
+ }
983
+ /**
984
+ * @description Reads the CD (Carrier Detect) control signal state
985
+ * @returns {Promise<boolean>} A promise that resolves to the CD state
986
+ */
987
+ async readCarrierDetect() {
988
+ try {
989
+ return await core.invoke('plugin:serialplugin|read_carrier_detect', {
990
+ path: this.options.path
991
+ });
992
+ }
993
+ catch (error) {
994
+ return Promise.reject(error);
995
+ }
996
+ }
997
+ /**
998
+ * @description Gets the number of bytes available to read
999
+ * @returns {Promise<number>} A promise that resolves to the number of bytes
1000
+ */
1001
+ async bytesToRead() {
1002
+ try {
1003
+ return await core.invoke('plugin:serialplugin|bytes_to_read', {
1004
+ path: this.options.path
1005
+ });
1006
+ }
1007
+ catch (error) {
1008
+ return Promise.reject(error);
1009
+ }
1010
+ }
1011
+ /**
1012
+ * @description Gets the number of bytes waiting to be written
1013
+ * @returns {Promise<number>} A promise that resolves to the number of bytes
1014
+ */
1015
+ async bytesToWrite() {
1016
+ try {
1017
+ return await core.invoke('plugin:serialplugin|bytes_to_write', {
1018
+ path: this.options.path
1019
+ });
1020
+ }
1021
+ catch (error) {
1022
+ return Promise.reject(error);
1023
+ }
1024
+ }
1025
+ /**
1026
+ * @description Clears the specified buffer
1027
+ * @param {ClearBuffer} buffer The buffer to clear
1028
+ * @returns {Promise<void>} A promise that resolves when the buffer is cleared
1029
+ */
1030
+ async clearBuffer(buffer) {
1031
+ try {
1032
+ return await core.invoke('plugin:serialplugin|clear_buffer', {
1033
+ path: this.options.path,
1034
+ bufferType: buffer
1035
+ });
1036
+ }
1037
+ catch (error) {
1038
+ return Promise.reject(error);
1039
+ }
1040
+ }
1041
+ /**
1042
+ * @description Starts transmitting a break signal
1043
+ * @returns {Promise<void>} A promise that resolves when break signal starts
1044
+ */
1045
+ async setBreak() {
1046
+ try {
1047
+ return await core.invoke('plugin:serialplugin|set_break', {
1048
+ path: this.options.path
1049
+ });
1050
+ }
1051
+ catch (error) {
1052
+ return Promise.reject(error);
1053
+ }
1054
+ }
1055
+ /**
1056
+ * @description Stops transmitting a break signal
1057
+ * @returns {Promise<void>} A promise that resolves when break signal stops
1058
+ */
1059
+ async clearBreak() {
1060
+ try {
1061
+ return await core.invoke('plugin:serialplugin|clear_break', {
1062
+ path: this.options.path
1063
+ });
1064
+ }
1065
+ catch (error) {
1066
+ return Promise.reject(error);
1067
+ }
1068
+ }
1069
+ /**
1070
+ * @description Writes string data to the serial port
1071
+ * @param {string} value The data to write
1072
+ * @returns {Promise<number>} A promise that resolves to the number of bytes written
1073
+ */
1074
+ async write(value) {
1075
+ try {
1076
+ if (!this.isOpen) {
1077
+ return Promise.reject(`serial port ${this.options.path} not opened!`);
1078
+ }
1079
+ return await core.invoke('plugin:serialplugin|write', {
1080
+ value,
1081
+ path: this.options.path,
1082
+ });
1083
+ }
1084
+ catch (error) {
1085
+ return Promise.reject(error);
1086
+ }
1087
+ }
1088
+ /**
1089
+ * @description Writes binary data to the serial port
1090
+ * @param {Uint8Array | number[]} value The binary data to write
1091
+ * @returns {Promise<number>} A promise that resolves to the number of bytes written
1092
+ */
1093
+ async writeBinary(value) {
1094
+ try {
1095
+ if (!this.isOpen) {
1096
+ return Promise.reject(`serial port ${this.options.path} not opened!`);
1097
+ }
1098
+ if (value instanceof Uint8Array || value instanceof Array) {
1099
+ return await core.invoke('plugin:serialplugin|write_binary', {
1100
+ value: Array.from(value),
1101
+ path: this.options.path,
1102
+ });
1103
+ }
1104
+ else {
1105
+ return Promise.reject('value Argument type error! Expected type: string, Uint8Array, number[]');
1106
+ }
1107
+ }
1108
+ catch (error) {
1109
+ return Promise.reject(error);
1110
+ }
1111
+ }
1112
+ }
1113
+
1114
+ exports.SerialPort = SerialPort;