webserial-core 1.1.2 → 1.1.4

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.
@@ -10,31 +10,94 @@ class m extends EventTarget {
10
10
  };
11
11
  __debug__ = !1;
12
12
  __listenersCallbacks__ = [];
13
+ /**
14
+ * Dispatches an event with the specified type and data
15
+ * @param type - The event type to dispatch
16
+ * @param data - Optional data to attach to the event
17
+ * @example
18
+ * ```typescript
19
+ * dispatcher.dispatch('connected', { port: 'COM3' });
20
+ * ```
21
+ */
13
22
  dispatch(e, t = null) {
14
- const i = new g(e, { detail: t });
15
- this.dispatchEvent(i), this.__debug__ && this.dispatchEvent(new g("debug", { detail: { type: e, data: t } }));
16
- }
17
- dispatchAsync(e, t = null, i = 100) {
18
- const n = this;
23
+ const n = new g(e, { detail: t });
24
+ this.dispatchEvent(n), this.__debug__ && this.dispatchEvent(new g("debug", { detail: { type: e, data: t } }));
25
+ }
26
+ /**
27
+ * Dispatches an event asynchronously after a specified delay
28
+ * @param type - The event type to dispatch
29
+ * @param data - Optional data to attach to the event
30
+ * @param ms - Delay in milliseconds (default: 100)
31
+ * @example
32
+ * ```typescript
33
+ * dispatcher.dispatchAsync('timeout', { reason: 'no response' }, 500);
34
+ * ```
35
+ */
36
+ dispatchAsync(e, t = null, n = 100) {
37
+ const i = this;
19
38
  setTimeout(() => {
20
- n.dispatch(e, t);
21
- }, i);
22
- }
39
+ i.dispatch(e, t);
40
+ }, n);
41
+ }
42
+ /**
43
+ * Registers an event listener for the specified event type
44
+ * @param type - The event type to listen to
45
+ * @param callback - The callback function to execute when the event is triggered
46
+ * @example
47
+ * ```typescript
48
+ * dispatcher.on('connected', (event) => {
49
+ * console.log('Device connected', event.detail);
50
+ * });
51
+ * ```
52
+ */
23
53
  on(e, t) {
24
54
  typeof this.__listeners__[e] < "u" && !this.__listeners__[e] && (this.__listeners__[e] = !0), this.__listenersCallbacks__.push({ key: e, callback: t }), this.addEventListener(e, t);
25
55
  }
56
+ /**
57
+ * Removes an event listener for the specified event type
58
+ * @param type - The event type to stop listening to
59
+ * @param callback - The callback function to remove
60
+ * @example
61
+ * ```typescript
62
+ * const handler = (event) => console.log(event.detail);
63
+ * dispatcher.on('data', handler);
64
+ * dispatcher.off('data', handler);
65
+ * ```
66
+ */
26
67
  off(e, t) {
27
- this.__listenersCallbacks__ = this.__listenersCallbacks__.filter((i) => !(i.key === e && i.callback === t)), this.removeEventListener(e, t);
68
+ this.__listenersCallbacks__ = this.__listenersCallbacks__.filter((n) => !(n.key === e && n.callback === t)), this.removeEventListener(e, t);
28
69
  }
70
+ /**
71
+ * Registers an available listener type for tracking
72
+ * @param type - The event type to register
73
+ * @internal
74
+ */
29
75
  serialRegisterAvailableListener(e) {
30
76
  this.__listeners__[e] || (this.__listeners__[e] = !1);
31
77
  }
78
+ /**
79
+ * Gets the list of all available listeners and their state
80
+ * @returns Array of listener objects with type and listening status
81
+ * @example
82
+ * ```typescript
83
+ * const listeners = dispatcher.availableListeners;
84
+ * console.log(listeners); // [{ type: 'connected', listening: true }, ...]
85
+ * ```
86
+ */
32
87
  get availableListeners() {
33
88
  return Object.keys(this.__listeners__).sort().map((t) => ({
34
89
  type: t,
35
90
  listening: this.__listeners__[t]
36
91
  }));
37
92
  }
93
+ /**
94
+ * Removes all event listeners except internal ones (like queue listeners)
95
+ * Resets all listener states to false
96
+ * @example
97
+ * ```typescript
98
+ * dispatcher.removeAllListeners();
99
+ * ```
100
+ */
38
101
  removeAllListeners() {
39
102
  for (const e of this.__listenersCallbacks__)
40
103
  ["internal:queue"].includes(e.key) || (this.__listenersCallbacks__ = this.__listenersCallbacks__.filter((t) => !(t.key === e.key && t.callback === e.callback)), this.removeEventListener(e.key, e.callback));
@@ -57,17 +120,44 @@ class s extends m {
57
120
  const t = new Error();
58
121
  throw t.message = `Type ${e} is not supported`, t.name = "DeviceTypeError", t;
59
122
  }
123
+ /**
124
+ * Registers a new device type in the registry
125
+ * @param type - The type name of the device (e.g., 'arduino', 'esp32')
126
+ * @internal
127
+ */
60
128
  static registerType(e) {
61
129
  typeof s.devices[e] > "u" && (s.devices = { ...s.devices, [e]: {} });
62
130
  }
131
+ /**
132
+ * Adds a device to the registry
133
+ * @param device - The Core device instance to add
134
+ * @returns The index of the device in its type registry
135
+ * @throws {Error} If device with the same ID already exists
136
+ * @example
137
+ * ```typescript
138
+ * const arduino = new Arduino();
139
+ * Devices.add(arduino);
140
+ * ```
141
+ */
63
142
  static add(e) {
64
143
  const t = e.typeDevice;
65
144
  typeof s.devices[t] > "u" && s.registerType(t);
66
- const i = e.uuid;
67
- if (typeof s.devices[t] > "u" && s.typeError(t), s.devices[t][i])
68
- throw new Error(`Device with id ${i} already exists`);
69
- return s.devices[t][i] = e, s.$dispatchChange(e), Object.keys(s.devices[t]).indexOf(i);
70
- }
145
+ const n = e.uuid;
146
+ if (typeof s.devices[t] > "u" && s.typeError(t), s.devices[t][n])
147
+ throw new Error(`Device with id ${n} already exists`);
148
+ return s.devices[t][n] = e, s.$dispatchChange(e), Object.keys(s.devices[t]).indexOf(n);
149
+ }
150
+ /**
151
+ * Gets a specific device by type and UUID
152
+ * @param type - The device type
153
+ * @param id - The device UUID
154
+ * @returns The device instance
155
+ * @throws {Error} If the device type is not supported
156
+ * @example
157
+ * ```typescript
158
+ * const device = Devices.get('arduino', 'uuid-123');
159
+ * ```
160
+ */
71
161
  static get(e, t) {
72
162
  return typeof s.devices[e] > "u" && s.registerType(e), typeof s.devices[e] > "u" && s.typeError(e), s.devices[e][t];
73
163
  }
@@ -78,10 +168,10 @@ class s extends m {
78
168
  return Object.values(s.devices).map((t) => Object.values(t)).flat();
79
169
  }
80
170
  static getByNumber(e, t) {
81
- return typeof s.devices[e] > "u" && s.typeError(e), Object.values(s.devices[e]).find((n) => n.deviceNumber === t) ?? null;
171
+ return typeof s.devices[e] > "u" && s.typeError(e), Object.values(s.devices[e]).find((i) => i.deviceNumber === t) ?? null;
82
172
  }
83
173
  static getCustom(e, t = 1) {
84
- return typeof s.devices[e] > "u" && s.typeError(e), Object.values(s.devices[e]).find((n) => n.deviceNumber === t) ?? null;
174
+ return typeof s.devices[e] > "u" && s.typeError(e), Object.values(s.devices[e]).find((i) => i.deviceNumber === t) ?? null;
85
175
  }
86
176
  static async connectToAll() {
87
177
  const e = s.getList();
@@ -117,27 +207,42 @@ class s extends m {
117
207
  }
118
208
  }
119
209
  s.instance || (s.instance = new s());
120
- function y(c = 100) {
210
+ function y(o = 100) {
121
211
  return new Promise(
122
- (e) => setTimeout(() => e(), c)
212
+ (e) => setTimeout(() => e(), o)
123
213
  );
124
214
  }
125
- class w {
126
- #t = "http://localhost:3000";
215
+ class C {
216
+ #n = "http://localhost:3000";
127
217
  #i = {
128
218
  transports: ["websocket"]
129
219
  };
130
- #e;
131
- #r = !1;
132
- #a = {};
220
+ #e = null;
221
+ #s = !1;
222
+ #a = !1;
223
+ #t;
224
+ constructor() {
225
+ this.#t = {
226
+ onResponse: this.onResponse.bind(this),
227
+ onDisconnect: () => {
228
+ this.#s = !1, window.dispatchEvent(new Event("serial:socket:disconnected"));
229
+ },
230
+ onConnect: () => {
231
+ this.#s = !0, window.dispatchEvent(new Event("serial:socket:connected"));
232
+ },
233
+ onConnectError: (e) => {
234
+ console.debug("Socket connection error", e), this.#s = !1, window.dispatchEvent(new Event("serial:socket:disconnected"));
235
+ }
236
+ };
237
+ }
133
238
  set uri(e) {
134
239
  const t = new URL(e);
135
240
  if (!["http:", "https:", "ws:", "wss:"].includes(t.protocol))
136
241
  throw new Error("URI must start with http://, https://, ws://, or wss://");
137
- this.#t = e;
242
+ this.#n = e;
138
243
  }
139
244
  get uri() {
140
- return this.#t;
245
+ return this.#n;
141
246
  }
142
247
  set options(e) {
143
248
  if (typeof e != "object")
@@ -147,33 +252,47 @@ class w {
147
252
  get options() {
148
253
  return this.#i;
149
254
  }
150
- constructor() {
151
- this.#a.onResponse = this.onResponse.bind(this);
255
+ get socketId() {
256
+ return this.#e && this.#e.id ? this.#e.id : null;
152
257
  }
153
258
  disconnect() {
154
- this.#e && (this.#e.off("response", this.#a.onResponse), this.#e.disconnect(), this.#e = null), this.#r = !1;
259
+ this.#e && (this.#e.off("response", this.#t.onResponse), this.#e.off("disconnect", this.#t.onDisconnect), this.#e.off("connect", this.#t.onConnect), this.#e.off("connect_error", this.#t.onConnectError), this.#e.disconnect(), this.#e = null, this.#a = !1), this.#s = !1;
155
260
  }
156
261
  prepare() {
157
- this.#r || (this.#e = b(this.#t, this.#i), this.#r = !0, this.#e.on("response", this.#a.onResponse));
262
+ this.#s || this.#a || (this.#e = b(this.#n, this.#i), this.#a = !0, this.#e.on("disconnect", this.#t.onDisconnect), this.#e.on("response", this.#t.onResponse), this.#e.on("connect", this.#t.onConnect), this.#e.on("connect_error", this.#t.onConnectError));
158
263
  }
159
264
  connectDevice(e) {
265
+ if (!this.#e)
266
+ throw new Error("Socket not connected. Call prepare() first.");
160
267
  this.#e.emit("connectDevice", { config: e });
161
268
  }
162
269
  disconnectDevice(e) {
270
+ if (!this.#e)
271
+ throw new Error("Socket not connected. Call prepare() first.");
163
272
  this.#e.emit("disconnectDevice", { config: e });
164
273
  }
165
274
  disconnectAllDevices() {
275
+ if (!this.#e)
276
+ throw new Error("Socket not connected. Call prepare() first.");
166
277
  this.#e.emit("disconnectAll");
167
278
  }
168
279
  write(e) {
280
+ if (!this.#e)
281
+ throw new Error("Socket not connected. Call prepare() first.");
169
282
  this.#e.emit("cmd", e);
170
283
  }
171
284
  onResponse(e) {
172
285
  let t = s.get(e.name, e.uuid);
173
286
  t || (t = s.getByNumber(e.name, e.deviceNumber)), t && t.socketResponse(e);
174
287
  }
288
+ isConnected() {
289
+ return this.#s;
290
+ }
291
+ isDisconnected() {
292
+ return !this.#s;
293
+ }
175
294
  }
176
- const u = new w(), p = {
295
+ const c = new C(), p = {
177
296
  baudRate: 9600,
178
297
  dataBits: 8,
179
298
  stopBits: 1,
@@ -181,7 +300,7 @@ const u = new w(), p = {
181
300
  bufferSize: 32768,
182
301
  flowControl: "none"
183
302
  };
184
- class v extends m {
303
+ class S extends m {
185
304
  __internal__ = {
186
305
  bypassSerialBytesConnection: !1,
187
306
  auto_response: !1,
@@ -255,12 +374,12 @@ class v extends m {
255
374
  reconnection: 0
256
375
  }
257
376
  };
258
- #t = null;
377
+ #n = null;
259
378
  constructor({
260
379
  filters: e = null,
261
380
  config_port: t = p,
262
- no_device: i = 1,
263
- device_listen_on_channel: n = 1,
381
+ no_device: n = 1,
382
+ device_listen_on_channel: i = 1,
264
383
  bypassSerialBytesConnection: a = !1,
265
384
  socket: r = !1
266
385
  } = {
@@ -273,7 +392,7 @@ class v extends m {
273
392
  }) {
274
393
  if (super(), !("serial" in navigator))
275
394
  throw new Error("Web Serial not supported");
276
- e && (this.serialFilters = e), t && (this.serialConfigPort = t), a && (this.__internal__.bypassSerialBytesConnection = a), i && this.#w(i), n && ["number", "string"].includes(typeof n) && (this.listenOnChannel = n), this.__internal__.serial.socket = r, this.#g(), this.#y();
395
+ e && (this.serialFilters = e), t && (this.serialConfigPort = t), a && (this.__internal__.bypassSerialBytesConnection = a), n && this.#b(n), i && ["number", "string"].includes(typeof i) && (this.listenOnChannel = i), this.__internal__.serial.socket = r, this.#g(), this.#y();
277
396
  }
278
397
  set listenOnChannel(e) {
279
398
  if (typeof e == "string" && (e = parseInt(e)), isNaN(e) || e < 1 || e > 255)
@@ -315,7 +434,7 @@ class v extends m {
315
434
  }
316
435
  get isDisconnected() {
317
436
  const e = this.__internal__.serial.connected, t = this.#i(this.__internal__.serial.port);
318
- return !e && t && (this.dispatch("serial:connected"), this.#s(!1), s.$dispatchChange(this)), this.__internal__.serial.connected = t, !this.__internal__.serial.connected;
437
+ return !e && t && (this.dispatch("serial:connected"), this.#o(!1), s.$dispatchChange(this)), this.__internal__.serial.connected = t, !this.__internal__.serial.connected;
319
438
  }
320
439
  get deviceNumber() {
321
440
  return this.__internal__.device_number;
@@ -489,7 +608,7 @@ class v extends m {
489
608
  };
490
609
  }
491
610
  #i(e) {
492
- return this.useSocket ? this.__internal__.serial.connected : !!(e && e.readable && e.writable);
611
+ return this.useSocket ? this.__internal__.serial.connected && c.isConnected() : !!(e && e.readable && e.writable);
493
612
  }
494
613
  async timeout(e, t) {
495
614
  this.__internal__.last_error.message = "Operation response timed out.", this.__internal__.last_error.action = t, this.__internal__.last_error.code = e, this.__internal__.timeout.until_response && (clearTimeout(this.__internal__.timeout.until_response), this.__internal__.timeout.until_response = 0), t === "connect" ? (this.__internal__.serial.connected = !1, this.dispatch("serial:reconnect", {}), s.$dispatchChange(this)) : t === "connection:start" && (await this.serialDisconnect(), this.__internal__.serial.connected = !1, this.__internal__.aux_port_connector += 1, s.$dispatchChange(this), await this.serialConnect()), this.__internal__.serial.queue.length > 0 && this.dispatch("internal:queue", {}), this.dispatch("serial:timeout", {
@@ -504,24 +623,24 @@ class v extends m {
504
623
  #e(e = null) {
505
624
  this.__internal__.serial.connected = !1, this.__internal__.aux_port_connector = 0, this.dispatch("serial:disconnected", e), s.$dispatchChange(this);
506
625
  }
507
- #r(e) {
626
+ #s(e) {
508
627
  this.__internal__.serial.aux_connecting = e.detail.active ? "connecting" : "finished";
509
628
  }
510
629
  socketResponse(e) {
511
630
  const t = this.__internal__.serial.connected;
512
- if (e.type === "disconnect" || e.type === "error" && e.data === "DISCONNECTED" ? this.__internal__.serial.connected = !1 : e.type === "success" && (this.__internal__.serial.connected = !0), s.$dispatchChange(this), !t && this.__internal__.serial.connected && (this.dispatch("serial:connected"), this.#s(!1)), e.type === "success")
513
- this.#n(new Uint8Array(e.data));
631
+ if (e.type === "disconnect" || e.type === "error" && e.data === "DISCONNECTED" ? this.__internal__.serial.connected = !1 : e.type === "success" && (this.__internal__.serial.connected = !0), s.$dispatchChange(this), !t && this.__internal__.serial.connected && (this.dispatch("serial:connected"), this.#o(!1)), e.type === "success")
632
+ this.#r(new Uint8Array(e.data));
514
633
  else if (e.type === "error") {
515
- const i = new Error("The port is closed or is not readable/writable");
516
- this.serialErrors(i);
634
+ const n = new Error("The port is closed or is not readable/writable");
635
+ this.serialErrors(n);
517
636
  } else e.type === "timeout" && this.timeout(e.data.bytes ?? [], this.lastAction || "unknown");
518
637
  this.__internal__.serial.last_action = null;
519
638
  }
520
639
  async connect() {
521
640
  return this.isConnected ? !0 : (this.__internal__.serial.aux_connecting = "idle", new Promise((e, t) => {
522
- this.#t || (this.#t = this.#r.bind(this)), this.on("internal:connecting", this.#t);
523
- const i = setInterval(() => {
524
- this.__internal__.serial.aux_connecting === "finished" ? (clearInterval(i), this.__internal__.serial.aux_connecting = "idle", this.#t !== null && this.off("internal:connecting", this.#t), this.isConnected ? e(!0) : t(`${this.typeDevice} device ${this.deviceNumber} not connected`)) : this.__internal__.serial.aux_connecting === "connecting" && (this.__internal__.serial.aux_connecting = "idle", this.dispatch("internal:connecting", { active: !0 }), this.dispatch("serial:connecting", { active: !0 }));
641
+ this.#n || (this.#n = this.#s.bind(this)), this.on("internal:connecting", this.#n);
642
+ const n = setInterval(() => {
643
+ this.__internal__.serial.aux_connecting === "finished" ? (clearInterval(n), this.__internal__.serial.aux_connecting = "idle", this.#n !== null && this.off("internal:connecting", this.#n), this.isConnected ? e(!0) : t(`${this.typeDevice} device ${this.deviceNumber} not connected`)) : this.__internal__.serial.aux_connecting === "connecting" && (this.__internal__.serial.aux_connecting = "idle", this.dispatch("internal:connecting", { active: !0 }), this.dispatch("serial:connecting", { active: !0 }));
525
644
  }, 100);
526
645
  this.serialConnect();
527
646
  }));
@@ -529,10 +648,10 @@ class v extends m {
529
648
  async serialDisconnect() {
530
649
  try {
531
650
  if (this.useSocket)
532
- u.disconnectDevice(this.configDeviceSocket);
651
+ c.isConnected() && c.disconnectDevice(this.configDeviceSocket);
533
652
  else {
534
653
  const e = this.__internal__.serial.reader, t = this.__internal__.serial.output_stream;
535
- e && (await e.cancel().catch((n) => this.serialErrors(n)), await this.__internal__.serial.input_done), t && (await t.getWriter().close(), await this.__internal__.serial.output_done), this.__internal__.serial.connected && this.__internal__.serial && this.__internal__.serial.port && await this.__internal__.serial.port.close();
654
+ e && (await e.cancel().catch((i) => this.serialErrors(i)), await this.__internal__.serial.input_done), t && (await t.getWriter().close(), await this.__internal__.serial.output_done), this.__internal__.serial.connected && this.__internal__.serial && this.__internal__.serial.port && await this.__internal__.serial.port.close();
536
655
  }
537
656
  } catch (e) {
538
657
  this.serialErrors(e);
@@ -541,12 +660,14 @@ class v extends m {
541
660
  }
542
661
  }
543
662
  async #a(e) {
663
+ if (c.isDisconnected())
664
+ throw this.#e({ error: "Socket is disconnected." }), new Error("The socket is disconnected");
544
665
  if (this.isDisconnected)
545
666
  throw this.#e({ error: "Port is closed, not readable or writable." }), new Error("The port is closed or is not readable/writable");
546
667
  const t = this.validateBytes(e);
547
- u.write({ config: this.configDeviceSocket, bytes: Array.from(t) });
668
+ c.write({ config: this.configDeviceSocket, bytes: Array.from(t) });
548
669
  }
549
- async #o(e) {
670
+ async #t(e) {
550
671
  if (this.useSocket) {
551
672
  await this.#a(e);
552
673
  return;
@@ -554,39 +675,39 @@ class v extends m {
554
675
  const t = this.__internal__.serial.port;
555
676
  if (!t || t && (!t.readable || !t.writable))
556
677
  throw this.#e({ error: "Port is closed, not readable or writable." }), new Error("The port is closed or is not readable/writable");
557
- const i = this.validateBytes(e);
678
+ const n = this.validateBytes(e);
558
679
  if (this.useRTSCTS && await this.#l(t, 5e3), t.writable === null) return;
559
- const n = t.writable.getWriter();
560
- await n.write(i), n.releaseLock();
680
+ const i = t.writable.getWriter();
681
+ await i.write(n), i.releaseLock();
561
682
  }
562
683
  async #l(e, t = 5e3) {
563
- const i = Date.now();
684
+ const n = Date.now();
564
685
  for (; ; ) {
565
- if (Date.now() - i > t)
686
+ if (Date.now() - n > t)
566
687
  throw new Error("Timeout waiting for clearToSend signal");
567
- const { clearToSend: n } = await e.getSignals();
568
- if (n) return;
688
+ const { clearToSend: i } = await e.getSignals();
689
+ if (i) return;
569
690
  await y(100);
570
691
  }
571
692
  }
572
- #n(e = new Uint8Array([]), t = !1) {
693
+ #r(e = new Uint8Array([]), t = !1) {
573
694
  if (e && e.length > 0) {
574
- const i = this.__internal__.serial.connected;
575
- if (this.__internal__.serial.connected = this.#i(this.__internal__.serial.port), s.$dispatchChange(this), !i && this.__internal__.serial.connected && (this.dispatch("serial:connected"), this.#s(!1)), this.__internal__.interval.reconnection && (clearInterval(this.__internal__.interval.reconnection), this.__internal__.interval.reconnection = 0), this.__internal__.timeout.until_response && (clearTimeout(this.__internal__.timeout.until_response), this.__internal__.timeout.until_response = 0), this.__internal__.serial.response.as === "hex")
695
+ const n = this.__internal__.serial.connected;
696
+ if (this.__internal__.serial.connected = this.#i(this.__internal__.serial.port), s.$dispatchChange(this), !n && this.__internal__.serial.connected && (this.dispatch("serial:connected"), this.#o(!1)), this.__internal__.interval.reconnection && (clearInterval(this.__internal__.interval.reconnection), this.__internal__.interval.reconnection = 0), this.__internal__.timeout.until_response && (clearTimeout(this.__internal__.timeout.until_response), this.__internal__.timeout.until_response = 0), this.__internal__.serial.response.as === "hex")
576
697
  t ? this.serialCorruptMessage(this.parseUint8ToHex(e)) : this.serialMessage(this.parseUint8ToHex(e));
577
698
  else if (this.__internal__.serial.response.as === "uint8")
578
699
  t ? this.serialCorruptMessage(e) : this.serialMessage(e);
579
700
  else if (this.__internal__.serial.response.as === "string") {
580
- const n = this.parseUint8ArrayToString(e);
701
+ const i = this.parseUint8ArrayToString(e);
581
702
  if (this.__internal__.serial.response.limiter !== null) {
582
- const a = n.split(this.__internal__.serial.response.limiter);
703
+ const a = i.split(this.__internal__.serial.response.limiter);
583
704
  for (const r in a)
584
705
  a[r] && (t ? this.serialCorruptMessage(a[r]) : this.serialMessage(a[r]));
585
706
  } else
586
- t ? this.serialCorruptMessage(n) : this.serialMessage(n);
707
+ t ? this.serialCorruptMessage(i) : this.serialMessage(i);
587
708
  } else {
588
- const n = this.stringToArrayBuffer(this.parseUint8ArrayToString(e));
589
- t ? this.serialCorruptMessage(n) : this.serialMessage(n);
709
+ const i = this.stringToArrayBuffer(this.parseUint8ArrayToString(e));
710
+ t ? this.serialCorruptMessage(i) : this.serialMessage(i);
590
711
  }
591
712
  }
592
713
  if (this.__internal__.serial.queue.length === 0) {
@@ -609,16 +730,16 @@ class v extends m {
609
730
  }
610
731
  async #_() {
611
732
  const e = this.serialFilters, t = await navigator.serial.getPorts({ filters: e });
612
- return e.length === 0 ? t : t.filter((n) => {
613
- const a = n.getInfo();
733
+ return e.length === 0 ? t : t.filter((i) => {
734
+ const a = i.getInfo();
614
735
  return e.some((r) => a.usbProductId === r.usbProductId && a.usbVendorId === r.usbVendorId);
615
- }).filter((n) => !this.#i(n));
736
+ }).filter((i) => !this.#i(i));
616
737
  }
617
738
  async serialPortsSaved(e) {
618
739
  const t = this.serialFilters;
619
740
  if (this.__internal__.aux_port_connector < e.length) {
620
- const i = this.__internal__.aux_port_connector;
621
- this.__internal__.serial.port = e[i];
741
+ const n = this.__internal__.aux_port_connector;
742
+ this.__internal__.serial.port = e[n];
622
743
  } else
623
744
  this.__internal__.aux_port_connector = 0, this.__internal__.serial.port = await navigator.serial.requestPort({
624
745
  filters: t
@@ -675,13 +796,13 @@ class v extends m {
675
796
  }
676
797
  #c(e) {
677
798
  if (e) {
678
- const t = this.__internal__.serial.response.buffer, i = new Uint8Array(t.length + e.byteLength);
679
- i.set(t, 0), i.set(new Uint8Array(e), t.length), this.__internal__.serial.response.buffer = i;
799
+ const t = this.__internal__.serial.response.buffer, n = new Uint8Array(t.length + e.byteLength);
800
+ n.set(t, 0), n.set(new Uint8Array(e), t.length), this.__internal__.serial.response.buffer = n;
680
801
  }
681
802
  }
682
803
  async #h() {
683
804
  this.__internal__.serial.time_until_send_bytes && (clearTimeout(this.__internal__.serial.time_until_send_bytes), this.__internal__.serial.time_until_send_bytes = 0), this.__internal__.serial.time_until_send_bytes = setTimeout(() => {
684
- this.__internal__.serial.response.buffer && this.#n(this.__internal__.serial.response.buffer), this.__internal__.serial.response.buffer = new Uint8Array(0);
805
+ this.__internal__.serial.response.buffer && this.#r(this.__internal__.serial.response.buffer), this.__internal__.serial.response.buffer = new Uint8Array(0);
685
806
  }, this.__internal__.serial.free_timeout_ms || 50);
686
807
  }
687
808
  async #u() {
@@ -689,11 +810,11 @@ class v extends m {
689
810
  let t = this.__internal__.serial.response.buffer;
690
811
  if (this.__internal__.serial.time_until_send_bytes && (clearTimeout(this.__internal__.serial.time_until_send_bytes), this.__internal__.serial.time_until_send_bytes = 0), !(e === null || !t || t.length === 0)) {
691
812
  for (; t.length >= e; ) {
692
- const i = t.slice(0, e);
693
- this.#n(i), t = t.slice(e);
813
+ const n = t.slice(0, e);
814
+ this.#r(n), t = t.slice(e);
694
815
  }
695
816
  this.__internal__.serial.response.buffer = t, t.length > 0 && (this.__internal__.serial.time_until_send_bytes = setTimeout(() => {
696
- this.#n(this.__internal__.serial.response.buffer, !0);
817
+ this.#r(this.__internal__.serial.response.buffer, !0);
697
818
  }, this.__internal__.serial.free_timeout_ms || 50));
698
819
  }
699
820
  }
@@ -701,54 +822,54 @@ class v extends m {
701
822
  const {
702
823
  limiter: e,
703
824
  prefixLimiter: t = !1,
704
- sufixLimiter: i = !0
825
+ sufixLimiter: n = !0
705
826
  } = this.__internal__.serial.response;
706
827
  if (!e)
707
828
  throw new Error("No limiter defined for delimited serial response");
708
- const n = this.__internal__.serial.response.buffer;
709
- if (!e || !n || n.length === 0) return;
829
+ const i = this.__internal__.serial.response.buffer;
830
+ if (!e || !i || i.length === 0) return;
710
831
  this.__internal__.serial.time_until_send_bytes && (clearTimeout(this.__internal__.serial.time_until_send_bytes), this.__internal__.serial.time_until_send_bytes = 0);
711
- let r = new TextDecoder().decode(n);
712
- const h = [];
832
+ let r = new TextDecoder().decode(i);
833
+ const u = [];
713
834
  if (typeof e == "string") {
714
- let o;
715
- if (t && i)
716
- o = new RegExp(`${e}([^${e}]+)${e}`, "g");
835
+ let l;
836
+ if (t && n)
837
+ l = new RegExp(`${e}([^${e}]+)${e}`, "g");
717
838
  else if (t)
718
- o = new RegExp(`${e}([^${e}]*)`, "g");
719
- else if (i)
720
- o = new RegExp(`([^${e}]+)${e}`, "g");
839
+ l = new RegExp(`${e}([^${e}]*)`, "g");
840
+ else if (n)
841
+ l = new RegExp(`([^${e}]+)${e}`, "g");
721
842
  else
722
843
  return;
723
- let _, l = 0;
724
- for (; (_ = o.exec(r)) !== null; )
725
- h.push(new TextEncoder().encode(_[1])), l = o.lastIndex;
726
- r = r.slice(l);
844
+ let h, _ = 0;
845
+ for (; (h = l.exec(r)) !== null; )
846
+ u.push(new TextEncoder().encode(h[1])), _ = l.lastIndex;
847
+ r = r.slice(_);
727
848
  } else if (e instanceof RegExp) {
728
- let o, _ = 0;
729
- if (t && i) {
730
- const l = new RegExp(`${e.source}(.*?)${e.source}`, "g");
731
- for (; (o = l.exec(r)) !== null; )
732
- h.push(new TextEncoder().encode(o[1])), _ = l.lastIndex;
733
- } else if (i)
734
- for (; (o = e.exec(r)) !== null; ) {
735
- const l = o.index, d = r.slice(_, l);
736
- h.push(new TextEncoder().encode(d)), _ = e.lastIndex;
849
+ let l, h = 0;
850
+ if (t && n) {
851
+ const _ = new RegExp(`${e.source}(.*?)${e.source}`, "g");
852
+ for (; (l = _.exec(r)) !== null; )
853
+ u.push(new TextEncoder().encode(l[1])), h = _.lastIndex;
854
+ } else if (n)
855
+ for (; (l = e.exec(r)) !== null; ) {
856
+ const _ = l.index, d = r.slice(h, _);
857
+ u.push(new TextEncoder().encode(d)), h = e.lastIndex;
737
858
  }
738
859
  else if (t) {
739
- const l = r.split(e);
740
- l.shift();
741
- for (const d of l)
742
- h.push(new TextEncoder().encode(d));
860
+ const _ = r.split(e);
861
+ _.shift();
862
+ for (const d of _)
863
+ u.push(new TextEncoder().encode(d));
743
864
  r = "";
744
865
  }
745
- r = r.slice(_);
866
+ r = r.slice(h);
746
867
  }
747
- for (const o of h)
748
- this.#n(o);
868
+ for (const l of u)
869
+ this.#r(l);
749
870
  const f = new TextEncoder().encode(r);
750
871
  this.__internal__.serial.response.buffer = f, f.length > 0 && (this.__internal__.serial.time_until_send_bytes = setTimeout(() => {
751
- this.#n(this.__internal__.serial.response.buffer, !0), this.__internal__.serial.response.buffer = new Uint8Array(0);
872
+ this.#r(this.__internal__.serial.response.buffer, !0), this.__internal__.serial.response.buffer = new Uint8Array(0);
752
873
  }, this.__internal__.serial.free_timeout_ms ?? 50));
753
874
  }
754
875
  async #p() {
@@ -758,56 +879,58 @@ class v extends m {
758
879
  this.__internal__.serial.reader = t;
759
880
  try {
760
881
  for (; this.__internal__.serial.keep_reading; ) {
761
- const { value: i, done: n } = await t.read();
762
- if (n) break;
763
- this.#c(i), this.__internal__.serial.response.delimited ? await this.#d() : this.__internal__.serial.response.length === null ? await this.#h() : await this.#u();
882
+ const { value: n, done: i } = await t.read();
883
+ if (i) break;
884
+ this.#c(n), this.__internal__.serial.response.delimited ? await this.#d() : this.__internal__.serial.response.length === null ? await this.#h() : await this.#u();
764
885
  }
765
- } catch (i) {
766
- this.serialErrors(i);
886
+ } catch (n) {
887
+ this.serialErrors(n);
767
888
  } finally {
768
889
  t.releaseLock(), this.__internal__.serial.keep_reading = !0, this.__internal__.serial.port && await this.__internal__.serial.port.close();
769
890
  }
770
891
  }
771
- #s(e) {
892
+ #o(e) {
772
893
  e !== this.__internal__.serial.connecting && (this.__internal__.serial.connecting = e, this.dispatch("serial:connecting", { active: e }), this.dispatch("internal:connecting", { active: e }));
773
894
  }
774
895
  async serialConnect() {
775
896
  try {
776
- if (this.#s(!0), this.useSocket)
777
- u.prepare(), this.__internal__.serial.last_action = "connect", this.__internal__.timeout.until_response = setTimeout(async () => {
897
+ if (this.#o(!0), this.useSocket) {
898
+ if (c.prepare(), this.__internal__.serial.last_action = "connect", this.__internal__.timeout.until_response = setTimeout(async () => {
778
899
  await this.timeout(this.__internal__.serial.bytes_connection ?? [], "connection:start");
779
- }, this.__internal__.time.response_connection), u.connectDevice(this.configDeviceSocket), this.dispatch("serial:sent", {
900
+ }, this.__internal__.time.response_connection), c.isDisconnected())
901
+ return;
902
+ c.connectDevice(this.configDeviceSocket), this.dispatch("serial:sent", {
780
903
  action: "connect",
781
904
  bytes: this.__internal__.serial.bytes_connection
782
905
  });
783
- else {
906
+ } else {
784
907
  const e = await this.#_();
785
908
  if (e.length > 0)
786
909
  await this.serialPortsSaved(e);
787
910
  else {
788
- const n = this.serialFilters;
911
+ const i = this.serialFilters;
789
912
  this.__internal__.serial.port = await navigator.serial.requestPort({
790
- filters: n
913
+ filters: i
791
914
  });
792
915
  }
793
916
  const t = this.__internal__.serial.port;
794
917
  if (!t)
795
918
  throw new Error("No port selected by the user");
796
919
  await t.open(this.serialConfigPort);
797
- const i = this;
798
- t.onconnect = (n) => {
799
- i.dispatch("serial:connected", n), i.#s(!1), s.$dispatchChange(this), i.__internal__.serial.queue.length > 0 ? i.dispatch("internal:queue", {}) : i.__internal__.serial.running_queue = !1;
920
+ const n = this;
921
+ t.onconnect = (i) => {
922
+ n.dispatch("serial:connected", i), n.#o(!1), s.$dispatchChange(this), n.__internal__.serial.queue.length > 0 ? n.dispatch("internal:queue", {}) : n.__internal__.serial.running_queue = !1;
800
923
  }, t.ondisconnect = async () => {
801
- await i.disconnect();
924
+ await n.disconnect();
802
925
  }, await y(this.__internal__.serial.delay_first_connection), this.__internal__.timeout.until_response = setTimeout(async () => {
803
- await i.timeout(i.__internal__.serial.bytes_connection ?? [], "connection:start");
804
- }, this.__internal__.time.response_connection), this.__internal__.serial.last_action = "connect", await this.#o(this.__internal__.serial.bytes_connection ?? []), this.dispatch("serial:sent", {
926
+ await n.timeout(n.__internal__.serial.bytes_connection ?? [], "connection:start");
927
+ }, this.__internal__.time.response_connection), this.__internal__.serial.last_action = "connect", await this.#t(this.__internal__.serial.bytes_connection ?? []), this.dispatch("serial:sent", {
805
928
  action: "connect",
806
929
  bytes: this.__internal__.serial.bytes_connection
807
- }), this.__internal__.auto_response && this.#n(this.__internal__.serial.auto_response), await this.#p();
930
+ }), this.__internal__.auto_response && this.#r(this.__internal__.serial.auto_response), await this.#p();
808
931
  }
809
932
  } catch (e) {
810
- this.#s(!1), this.serialErrors(e);
933
+ this.#o(!1), this.serialErrors(e);
811
934
  }
812
935
  }
813
936
  async #f() {
@@ -827,8 +950,8 @@ class v extends m {
827
950
  }
828
951
  add0x(e) {
829
952
  const t = [];
830
- return e.forEach((i, n) => {
831
- t[n] = "0x" + i;
953
+ return e.forEach((n, i) => {
954
+ t[i] = "0x" + n;
832
955
  }), t;
833
956
  }
834
957
  bytesToHex(e) {
@@ -858,8 +981,15 @@ class v extends m {
858
981
  #y() {
859
982
  const e = this;
860
983
  this.on("internal:queue", async () => {
861
- await e.#b();
862
- }), this.#m();
984
+ await e.#w();
985
+ });
986
+ const t = () => {
987
+ e.isConnected && e.#e({ error: "Socket disconnected." });
988
+ }, n = () => {
989
+ e.isDisconnected && !e.isConnecting && e.serialConnect().catch(() => {
990
+ });
991
+ };
992
+ this.useSocket && (window.addEventListener("serial:socket:disconnected", t), window.addEventListener("serial:socket:connected", n)), this.#m();
863
993
  }
864
994
  #m() {
865
995
  const e = this;
@@ -868,7 +998,9 @@ class v extends m {
868
998
  });
869
999
  });
870
1000
  }
871
- async #b() {
1001
+ async #w() {
1002
+ if (this.useSocket && c.isDisconnected())
1003
+ return;
872
1004
  if (!this.#i(this.__internal__.serial.port)) {
873
1005
  this.#e({ error: "Port is closed, not readable or writable." }), await this.serialConnect();
874
1006
  return;
@@ -883,20 +1015,20 @@ class v extends m {
883
1015
  let t = this.__internal__.time.response_general;
884
1016
  if (e.action === "connect" && (t = this.__internal__.time.response_connection), this.__internal__.timeout.until_response = setTimeout(async () => {
885
1017
  await this.timeout(e.bytes, e.action);
886
- }, t), this.__internal__.serial.last_action = e.action ?? "unknown", await this.#o(e.bytes), this.dispatch("serial:sent", {
1018
+ }, t), this.__internal__.serial.last_action = e.action ?? "unknown", await this.#t(e.bytes), this.dispatch("serial:sent", {
887
1019
  action: e.action,
888
1020
  bytes: e.bytes
889
1021
  }), this.__internal__.auto_response) {
890
- let n = new Uint8Array(0);
1022
+ let i = new Uint8Array(0);
891
1023
  try {
892
- n = this.validateBytes(this.__internal__.serial.auto_response);
1024
+ i = this.validateBytes(this.__internal__.serial.auto_response);
893
1025
  } catch (a) {
894
1026
  this.serialErrors(a);
895
1027
  }
896
- this.#n(n);
1028
+ this.#r(i);
897
1029
  }
898
- const i = [...this.__internal__.serial.queue];
899
- this.__internal__.serial.queue = i.splice(1), this.__internal__.serial.queue.length > 0 && (this.__internal__.serial.running_queue = !0);
1030
+ const n = [...this.__internal__.serial.queue];
1031
+ this.__internal__.serial.queue = n.splice(1), this.__internal__.serial.queue.length > 0 && (this.__internal__.serial.running_queue = !0);
900
1032
  }
901
1033
  validateBytes(e) {
902
1034
  let t = new Uint8Array(0);
@@ -913,15 +1045,15 @@ class v extends m {
913
1045
  return t;
914
1046
  }
915
1047
  async appendToQueue(e, t) {
916
- const i = this.validateBytes(e);
1048
+ const n = this.validateBytes(e);
917
1049
  if (["connect", "connection:start"].includes(t)) {
918
1050
  if (this.__internal__.serial.connected) return;
919
1051
  await this.serialConnect();
920
1052
  return;
921
1053
  }
922
- this.__internal__.serial.queue.push({ bytes: i, action: t }), this.dispatch("internal:queue", {});
1054
+ this.__internal__.serial.queue.push({ bytes: n, action: t }), this.dispatch("internal:queue", {});
923
1055
  }
924
- #w(e = 1) {
1056
+ #b(e = 1) {
925
1057
  this.__internal__.device_number = e, !this.__internal__.bypassSerialBytesConnection && (this.__internal__.serial.bytes_connection = this.serialSetConnectionConstant(e));
926
1058
  }
927
1059
  serialSetConnectionConstant(e = 1) {
@@ -947,8 +1079,8 @@ class v extends m {
947
1079
  }
948
1080
  sumHex(e) {
949
1081
  let t = 0;
950
- return e.forEach((i) => {
951
- t += parseInt(i, 16);
1082
+ return e.forEach((n) => {
1083
+ t += parseInt(n, 16);
952
1084
  }), t.toString(16);
953
1085
  }
954
1086
  toString() {
@@ -982,13 +1114,13 @@ class v extends m {
982
1114
  }
983
1115
  parseStringToTextEncoder(e = "", t = `
984
1116
  `) {
985
- const i = new TextEncoder();
986
- return e += t, i.encode(e);
1117
+ const n = new TextEncoder();
1118
+ return e += t, n.encode(e);
987
1119
  }
988
1120
  parseStringToBytes(e = "", t = `
989
1121
  `) {
990
- const i = this.parseStringToTextEncoder(e, t);
991
- return Array.from(i).map((n) => n.toString(16));
1122
+ const n = this.parseStringToTextEncoder(e, t);
1123
+ return Array.from(n).map((i) => i.toString(16));
992
1124
  }
993
1125
  parseUint8ToHex(e) {
994
1126
  return Array.from(e).map((t) => t.toString(16).padStart(2, "0").toLowerCase());
@@ -998,28 +1130,28 @@ class v extends m {
998
1130
  }
999
1131
  stringArrayToUint8Array(e) {
1000
1132
  const t = [];
1001
- return typeof e == "string" ? this.parseStringToTextEncoder(e).buffer : (e.forEach((i) => {
1002
- const n = i.replace("0x", "");
1003
- t.push(parseInt(n, 16));
1133
+ return typeof e == "string" ? this.parseStringToTextEncoder(e).buffer : (e.forEach((n) => {
1134
+ const i = n.replace("0x", "");
1135
+ t.push(parseInt(i, 16));
1004
1136
  }), new Uint8Array(t));
1005
1137
  }
1006
1138
  parseUint8ArrayToString(e) {
1007
1139
  let t = new Uint8Array(0);
1008
1140
  e instanceof Uint8Array ? t = e : t = this.stringArrayToUint8Array(e), e = this.parseUint8ToHex(t);
1009
- const i = e.map((n) => parseInt(n, 16));
1010
- return this.__internal__.serial.response.replacer ? String.fromCharCode(...i).replace(this.__internal__.serial.response.replacer, "") : String.fromCharCode(...i);
1141
+ const n = e.map((i) => parseInt(i, 16));
1142
+ return this.__internal__.serial.response.replacer ? String.fromCharCode(...n).replace(this.__internal__.serial.response.replacer, "") : String.fromCharCode(...n);
1011
1143
  }
1012
1144
  hexToAscii(e) {
1013
1145
  const t = e.toString();
1014
- let i = "";
1015
- for (let n = 0; n < t.length; n += 2)
1016
- i += String.fromCharCode(parseInt(t.substring(n, 2), 16));
1017
- return i;
1146
+ let n = "";
1147
+ for (let i = 0; i < t.length; i += 2)
1148
+ n += String.fromCharCode(parseInt(t.substring(i, 2), 16));
1149
+ return n;
1018
1150
  }
1019
1151
  asciiToHex(e) {
1020
1152
  const t = [];
1021
- for (let i = 0, n = e.length; i < n; i++) {
1022
- const a = Number(e.charCodeAt(i)).toString(16);
1153
+ for (let n = 0, i = e.length; n < i; n++) {
1154
+ const a = Number(e.charCodeAt(n)).toString(16);
1023
1155
  t.push(a);
1024
1156
  }
1025
1157
  return t.join("");
@@ -1028,9 +1160,66 @@ class v extends m {
1028
1160
  return this.isConnected;
1029
1161
  }
1030
1162
  }
1163
+ var E = /* @__PURE__ */ ((o) => (o.CONNECTION_FAILED = "CONNECTION_FAILED", o.DISCONNECTION_FAILED = "DISCONNECTION_FAILED", o.WRITE_FAILED = "WRITE_FAILED", o.READ_FAILED = "READ_FAILED", o.TIMEOUT = "TIMEOUT", o.PORT_NOT_FOUND = "PORT_NOT_FOUND", o.PERMISSION_DENIED = "PERMISSION_DENIED", o.DEVICE_NOT_SUPPORTED = "DEVICE_NOT_SUPPORTED", o.INVALID_CONFIGURATION = "INVALID_CONFIGURATION", o.SOCKET_ERROR = "SOCKET_ERROR", o.UNKNOWN_ERROR = "UNKNOWN_ERROR", o))(E || {});
1164
+ class w extends Error {
1165
+ /**
1166
+ * Error code identifying the type of error
1167
+ */
1168
+ code;
1169
+ /**
1170
+ * Additional context about the error
1171
+ */
1172
+ context;
1173
+ /**
1174
+ * Timestamp when the error occurred
1175
+ */
1176
+ timestamp;
1177
+ /**
1178
+ * Creates a new SerialError
1179
+ * @param message - Human-readable error message
1180
+ * @param code - Error code from SerialErrorCode enum
1181
+ * @param context - Additional context information
1182
+ * @example
1183
+ * ```typescript
1184
+ * throw new SerialError(
1185
+ * 'Failed to connect to device',
1186
+ * SerialErrorCode.CONNECTION_FAILED,
1187
+ * { port: 'COM3', baudRate: 9600 }
1188
+ * );
1189
+ * ```
1190
+ */
1191
+ constructor(e, t = "UNKNOWN_ERROR", n) {
1192
+ super(e), this.name = "SerialError", this.code = t, this.context = n, this.timestamp = /* @__PURE__ */ new Date(), Error.captureStackTrace && Error.captureStackTrace(this, w);
1193
+ }
1194
+ /**
1195
+ * Returns a JSON representation of the error
1196
+ * @returns Serialized error object
1197
+ */
1198
+ toJSON() {
1199
+ return {
1200
+ name: this.name,
1201
+ message: this.message,
1202
+ code: this.code,
1203
+ context: this.context,
1204
+ timestamp: this.timestamp.toISOString(),
1205
+ stack: this.stack
1206
+ };
1207
+ }
1208
+ /**
1209
+ * Returns a formatted string representation of the error
1210
+ * @returns Formatted error string
1211
+ */
1212
+ toString() {
1213
+ const e = this.context ? ` | Context: ${JSON.stringify(this.context)}` : "";
1214
+ return `${this.name} [${this.code}]: ${this.message}${e}`;
1215
+ }
1216
+ }
1031
1217
  export {
1032
- v as Core,
1218
+ S as Core,
1033
1219
  s as Devices,
1034
1220
  m as Dispatcher,
1035
- u as Socket
1221
+ w as SerialError,
1222
+ E as SerialErrorCode,
1223
+ c as Socket
1036
1224
  };
1225
+ //# sourceMappingURL=webserial-core.js.map