webserial-core 2.0.3 → 2.1.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,20 @@
1
+ import { SerialParser } from '../types/index.js';
2
+ /**
3
+ * Creates a ccTalk parser that emits complete ccTalk packets as `Uint8Array`.
4
+ *
5
+ * @param maxDelayBetweenBytesMs - Maximum allowed silence between bytes before
6
+ * the buffer is discarded. Defaults to `50`.
7
+ * @returns A {@link SerialParser} that emits `Uint8Array` values.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * import { AbstractSerialDevice, ccTalk } from 'webserial-core';
12
+ *
13
+ * class CoinAcceptor extends AbstractSerialDevice<Uint8Array> {
14
+ * constructor() {
15
+ * super({ baudRate: 9600, parser: ccTalk(100) });
16
+ * }
17
+ * }
18
+ * ```
19
+ */
20
+ export declare function ccTalk(maxDelayBetweenBytesMs?: number): SerialParser<Uint8Array>;
@@ -1,11 +1,16 @@
1
1
  import { SerialParser } from '../types/index.js';
2
+ export interface DelimiterOptions {
3
+ /** Whether to include the delimiter at the end of each emitted value. Defaults to false. */
4
+ includeDelimiter?: boolean;
5
+ }
2
6
  /**
3
- * Creates a delimiter-based parser that splits the byte stream into
4
- * string messages separated by the given delimiter string.
7
+ * Creates a delimiter-based parser that splits the byte stream on the given
8
+ * delimiter and emits string messages.
5
9
  *
6
10
  * Commonly used with `'\n'` for Arduino `Serial.println()` output.
7
11
  *
8
12
  * @param char - The delimiter string (e.g. `'\n'`, `'\r\n'`, `';'`).
13
+ * @param options - Optional configuration.
9
14
  * @returns A {@link SerialParser} that emits `string` values.
10
15
  *
11
16
  * @example
@@ -19,4 +24,24 @@ import { SerialParser } from '../types/index.js';
19
24
  * }
20
25
  * ```
21
26
  */
22
- export declare function delimiter(char: string): SerialParser<string>;
27
+ export declare function delimiter(char: string, options?: DelimiterOptions): SerialParser<string>;
28
+ /**
29
+ * Creates a delimiter-based parser that splits the byte stream on the given
30
+ * binary delimiter and emits Uint8Array chunks.
31
+ *
32
+ * @param char - The delimiter as a `Uint8Array` or `number[]`.
33
+ * @param options - Optional configuration.
34
+ * @returns A {@link SerialParser} that emits `Uint8Array` values.
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * import { AbstractSerialDevice, delimiter } from 'webserial-core';
39
+ *
40
+ * class MyDevice extends AbstractSerialDevice<Uint8Array> {
41
+ * constructor() {
42
+ * super({ baudRate: 9600, parser: delimiter(new Uint8Array([0x0d, 0x0a])) });
43
+ * }
44
+ * }
45
+ * ```
46
+ */
47
+ export declare function delimiter(char: Uint8Array | number[], options?: DelimiterOptions): SerialParser<Uint8Array>;
@@ -0,0 +1,27 @@
1
+ import { SerialParser } from '../types/index.js';
2
+ export interface InterByteTimeoutOptions {
3
+ /** Period of silence in milliseconds after which buffered data is emitted. */
4
+ interval: number;
5
+ /** Maximum number of bytes to buffer before forcing an emit. Defaults to 65536. */
6
+ maxBufferSize?: number;
7
+ }
8
+ /**
9
+ * Creates an inter-byte timeout parser that buffers incoming bytes and emits
10
+ * the accumulated data after a silence period of at least `interval` ms, or
11
+ * when the buffer reaches `maxBufferSize`.
12
+ *
13
+ * @param options - Configuration options.
14
+ * @returns A {@link SerialParser} that emits `Uint8Array` values.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * import { AbstractSerialDevice, interByteTimeout } from 'webserial-core';
19
+ *
20
+ * class MyDevice extends AbstractSerialDevice<Uint8Array> {
21
+ * constructor() {
22
+ * super({ baudRate: 9600, parser: interByteTimeout({ interval: 30 }) });
23
+ * }
24
+ * }
25
+ * ```
26
+ */
27
+ export declare function interByteTimeout(options: InterByteTimeoutOptions): SerialParser<Uint8Array>;
@@ -0,0 +1,36 @@
1
+ import { SerialParser } from '../types/index.js';
2
+ export interface PacketLengthOptions {
3
+ /** Delimiter byte that marks the start of a packet. Defaults to `0xAA`. */
4
+ delimiter?: number;
5
+ /** Total overhead bytes in the packet (delimiter + length field(s) + any footer). Defaults to `2`. */
6
+ packetOverhead?: number;
7
+ /** Number of consecutive bytes that encode the payload length. Defaults to `1`. */
8
+ lengthBytes?: number;
9
+ /** Byte offset from the delimiter to the first length byte. Defaults to `1`. */
10
+ lengthOffset?: number;
11
+ /** Maximum allowed payload length. Packets exceeding this are discarded. Defaults to `0xFF`. */
12
+ maxLen?: number;
13
+ }
14
+ /**
15
+ * Creates a packet-length parser that buffers bytes, locates the delimiter,
16
+ * reads the embedded length field, and emits complete packets as `Uint8Array`.
17
+ *
18
+ * @param options - Configuration options.
19
+ * @returns A {@link SerialParser} that emits `Uint8Array` values.
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * import { AbstractSerialDevice, packetLength } from 'webserial-core';
24
+ *
25
+ * // Packets: [0xBC][0x00][len0][len1][cargo...][footer0][footer1]
26
+ * class MyDevice extends AbstractSerialDevice<Uint8Array> {
27
+ * constructor() {
28
+ * super({
29
+ * baudRate: 115200,
30
+ * parser: packetLength({ delimiter: 0xbc, packetOverhead: 5, lengthBytes: 2, lengthOffset: 2 }),
31
+ * });
32
+ * }
33
+ * }
34
+ * ```
35
+ */
36
+ export declare function packetLength(options?: PacketLengthOptions): SerialParser<Uint8Array>;
@@ -0,0 +1,28 @@
1
+ import { SerialParser } from '../types/index.js';
2
+ export interface ReadlineOptions {
3
+ /** Line delimiter. Defaults to `'\n'`. Accepts a string, Uint8Array, or number[]. */
4
+ delimiter?: string | Uint8Array | number[];
5
+ /** Include the delimiter at the end of each emitted string. Defaults to false. */
6
+ includeDelimiter?: boolean;
7
+ /** Text encoding used to decode bytes. Defaults to `'utf-8'`. */
8
+ encoding?: string;
9
+ }
10
+ /**
11
+ * Creates a readline parser that splits the byte stream on a newline (or
12
+ * custom delimiter) and emits each line as a decoded string.
13
+ *
14
+ * @param options - Optional configuration.
15
+ * @returns A {@link SerialParser} that emits `string` values.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * import { AbstractSerialDevice, readline } from 'webserial-core';
20
+ *
21
+ * class MyDevice extends AbstractSerialDevice<string> {
22
+ * constructor() {
23
+ * super({ baudRate: 9600, parser: readline() });
24
+ * }
25
+ * }
26
+ * ```
27
+ */
28
+ export declare function readline(options?: ReadlineOptions): SerialParser<string>;
@@ -0,0 +1,29 @@
1
+ import { SerialParser } from '../types/index.js';
2
+ export interface ReadyParserOptions {
3
+ /** Byte sequence that signals the device is ready. Accepts a string, Uint8Array, or number[]. */
4
+ delimiter: string | Uint8Array | number[];
5
+ /** Called once when the ready sequence is detected. */
6
+ onReady?: () => void;
7
+ }
8
+ /**
9
+ * Creates a ready parser that waits for the given delimiter sequence and then
10
+ * emits all subsequent data as raw `Uint8Array` chunks.
11
+ *
12
+ * @param options - Configuration options including the ready delimiter.
13
+ * @returns A {@link SerialParser} that emits `Uint8Array` values.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * import { AbstractSerialDevice, readyParser } from 'webserial-core';
18
+ *
19
+ * class MyDevice extends AbstractSerialDevice<Uint8Array> {
20
+ * constructor() {
21
+ * super({
22
+ * baudRate: 9600,
23
+ * parser: readyParser({ delimiter: 'READY\n', onReady: () => console.log('device ready') }),
24
+ * });
25
+ * }
26
+ * }
27
+ * ```
28
+ */
29
+ export declare function readyParser(options: ReadyParserOptions): SerialParser<Uint8Array>;
@@ -0,0 +1,26 @@
1
+ import { SerialParser } from '../types/index.js';
2
+ export interface RegexParserOptions {
3
+ /** Regular expression used to split the incoming text stream. */
4
+ regex: RegExp | string;
5
+ /** Text encoding used to decode bytes. Defaults to `'utf-8'`. */
6
+ encoding?: string;
7
+ }
8
+ /**
9
+ * Creates a regex parser that decodes incoming bytes and emits string segments
10
+ * split by the provided regular expression.
11
+ *
12
+ * @param options - Configuration options.
13
+ * @returns A {@link SerialParser} that emits `string` values.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * import { AbstractSerialDevice, regexParser } from 'webserial-core';
18
+ *
19
+ * class MyDevice extends AbstractSerialDevice<string> {
20
+ * constructor() {
21
+ * super({ baudRate: 9600, parser: regexParser({ regex: /[\r\n]+/ }) });
22
+ * }
23
+ * }
24
+ * ```
25
+ */
26
+ export declare function regexParser(options: RegexParserOptions): SerialParser<string>;
@@ -0,0 +1,58 @@
1
+ import { SerialParser } from '../types/index.js';
2
+ export interface SlipOptions {
3
+ /** Custom START byte. When set, each packet must begin with this byte. */
4
+ START?: number;
5
+ /** Escape byte for START. Defaults to `0xDB` (same as ESC). */
6
+ ESC_START?: number;
7
+ /** Escape byte. Defaults to `0xDB`. */
8
+ ESC?: number;
9
+ /** Packet end byte. Defaults to `0xC0`. */
10
+ END?: number;
11
+ /** ESC sequence for END byte. Defaults to `0xDC`. */
12
+ ESC_END?: number;
13
+ /** ESC sequence for ESC byte. Defaults to `0xDD`. */
14
+ ESC_ESC?: number;
15
+ /**
16
+ * Adds an END byte at the beginning of each packet (Bluetooth quirk).
17
+ * Only applies to `slipEncode`. Defaults to false.
18
+ */
19
+ bluetoothQuirk?: boolean;
20
+ }
21
+ /**
22
+ * Creates a SLIP decoder parser that strips framing and emits each decoded
23
+ * packet as a `Uint8Array`.
24
+ *
25
+ * @param options - Optional custom framing byte values.
26
+ * @returns A {@link SerialParser} that emits `Uint8Array` values.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * import { AbstractSerialDevice, slipDecoder } from 'webserial-core';
31
+ *
32
+ * class MyDevice extends AbstractSerialDevice<Uint8Array> {
33
+ * constructor() {
34
+ * super({ baudRate: 115200, parser: slipDecoder() });
35
+ * }
36
+ * }
37
+ * ```
38
+ */
39
+ export declare function slipDecoder(options?: SlipOptions): SerialParser<Uint8Array>;
40
+ /**
41
+ * SLIP-encodes a single outgoing packet.
42
+ *
43
+ * Escapes all END and ESC bytes in `data`, then appends an END byte.
44
+ * If `options.bluetoothQuirk` is true, an additional END byte is prepended.
45
+ *
46
+ * @param data - Raw packet bytes to encode.
47
+ * @param options - Optional custom framing byte values.
48
+ * @returns A new `Uint8Array` containing the SLIP-encoded packet.
49
+ *
50
+ * @example
51
+ * ```ts
52
+ * import { slipEncode } from 'webserial-core';
53
+ *
54
+ * const encoded = slipEncode(new Uint8Array([0x01, 0xC0, 0x02]));
55
+ * // device.send(encoded);
56
+ * ```
57
+ */
58
+ export declare function slipEncode(data: Uint8Array, options?: SlipOptions): Uint8Array;
@@ -0,0 +1,48 @@
1
+ import { SerialParser } from '../types/index.js';
2
+ export interface SpacePacketOptions {
3
+ /** Length in bytes of the Time Code Field in the secondary header. Defaults to 0. */
4
+ timeCodeFieldLength?: number;
5
+ /** Length in bytes of the Ancillary Data Field in the secondary header. Defaults to 0. */
6
+ ancillaryDataFieldLength?: number;
7
+ }
8
+ export interface SpacePacketHeader {
9
+ versionNumber: number;
10
+ identification: {
11
+ apid: number;
12
+ secondaryHeader: number;
13
+ type: number;
14
+ };
15
+ sequenceControl: {
16
+ packetName: number;
17
+ sequenceFlags: number;
18
+ };
19
+ dataLength: number;
20
+ }
21
+ export interface SpacePacketSecondaryHeader {
22
+ timeCode?: string;
23
+ ancillaryData?: string;
24
+ }
25
+ export interface SpacePacket {
26
+ header: SpacePacketHeader;
27
+ secondaryHeader?: SpacePacketSecondaryHeader;
28
+ data: string;
29
+ }
30
+ /**
31
+ * Creates a Space Packet Protocol parser that buffers bytes and emits a
32
+ * structured {@link SpacePacket} object for each complete packet received.
33
+ *
34
+ * @param options - Optional secondary-header field lengths.
35
+ * @returns A {@link SerialParser} that emits {@link SpacePacket} objects.
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * import { AbstractSerialDevice, spacePacket } from 'webserial-core';
40
+ *
41
+ * class TelemetryDevice extends AbstractSerialDevice<SpacePacket> {
42
+ * constructor() {
43
+ * super({ baudRate: 115200, parser: spacePacket({ timeCodeFieldLength: 8 }) });
44
+ * }
45
+ * }
46
+ * ```
47
+ */
48
+ export declare function spacePacket(options?: SpacePacketOptions): SerialParser<SpacePacket>;
@@ -2,6 +2,14 @@
2
2
  * @file parsers/index.ts
3
3
  * Re-exports all built-in parser factories.
4
4
  */
5
- export * from './FixedLengthParser.js';
5
+ export * from './CCTalkParser.js';
6
6
  export * from './DelimiterParser.js';
7
+ export * from './FixedLengthParser.js';
8
+ export * from './InterByteTimeoutParser.js';
9
+ export * from './PacketLengthParser.js';
7
10
  export * from './RawParser.js';
11
+ export * from './ReadlineParser.js';
12
+ export * from './ReadyParser.js';
13
+ export * from './RegexParser.js';
14
+ export * from './SlipParser.js';
15
+ export * from './SpacePacketParser.js';
@@ -1 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=class{listeners={};on(e,t){return this.listeners[e]||(this.listeners[e]=new Set),this.listeners[e].add(t),this}off(e,t){return this.listeners[e]&&this.listeners[e].delete(t),this}emit(e,...t){let n=this.listeners[e];if(!n||n.size===0)return!1;for(let e of n)e(...t);return!0}},t=class{static instances=new Set;static portInstanceMap=new WeakMap;static getInstances(){return Array.from(this.instances)}static register(e){this.instances.add(e)}static unregister(e){this.instances.delete(e)}static isPortInUse(e,t){let n=this.portInstanceMap.get(e);return n!==void 0&&n!==t}static lockPort(e,t){this.portInstanceMap.set(e,t)}static unlockPort(e){this.portInstanceMap.delete(e)}},n=class{queue=[];isProcessing=!1;isPaused=!0;timeoutId=null;commandTimeout;onSend;onTimeout;constructor(e){this.commandTimeout=e.commandTimeout,this.onSend=e.onSend,this.onTimeout=e.onTimeout}get queueSize(){return this.queue.length}enqueue(e){this.queue.push(e),this.tryProcessNext()}advance(){this.clearCommandTimeout(),this.isProcessing=!1,this.tryProcessNext()}pause(){this.isPaused=!0,this.clearCommandTimeout(),this.isProcessing=!1}resume(){this.isPaused=!1,this.tryProcessNext()}clear(){this.queue=[],this.clearCommandTimeout(),this.isProcessing=!1}snapshot(){return[...this.queue]}restore(e){this.queue=[...e,...this.queue]}tryProcessNext(){if(this.isPaused||this.isProcessing||this.queue.length===0)return;this.isProcessing=!0;let e=this.queue.shift();this.commandTimeout>0&&(this.timeoutId=setTimeout(()=>{this.timeoutId=null,this.onTimeout(e),this.advance()},this.commandTimeout)),this.onSend(e).catch(()=>{this.advance()})}clearCommandTimeout(){this.timeoutId!==null&&(clearTimeout(this.timeoutId),this.timeoutId=null)}},r=class e extends Error{constructor(t){super(t),this.name=`SerialPortConflictError`,Object.setPrototypeOf(this,e.prototype)}},i=class e extends Error{constructor(t){super(t),this.name=`SerialPermissionError`,Object.setPrototypeOf(this,e.prototype)}},a=class e extends Error{constructor(t){super(t),this.name=`SerialTimeoutError`,Object.setPrototypeOf(this,e.prototype)}},o=class e extends Error{constructor(t){super(t),this.name=`SerialReadError`,Object.setPrototypeOf(this,e.prototype)}},s=class e extends Error{constructor(t){super(t),this.name=`SerialWriteError`,Object.setPrototypeOf(this,e.prototype)}},c=class r extends e{port=null;reader=null;writer=null;queue;options;isConnecting=!1;abortController=null;userInitiatedDisconnect=!1;reconnectTimerId=null;isHandshaking=!1;static customProvider=null;static polyfillOptions;constructor(e){super(),this.options={baudRate:e.baudRate,dataBits:e.dataBits??8,stopBits:e.stopBits??1,parity:e.parity??`none`,bufferSize:e.bufferSize??255,flowControl:e.flowControl??`none`,filters:e.filters??[],commandTimeout:e.commandTimeout??0,parser:e.parser,autoReconnect:e.autoReconnect??!1,autoReconnectInterval:e.autoReconnectInterval??1500,handshakeTimeout:e.handshakeTimeout??2e3,provider:e.provider,polyfillOptions:e.polyfillOptions},this.queue=new n({commandTimeout:this.options.commandTimeout,onSend:async e=>{await this.writeToPort(e),this.emit(`serial:sent`,e,this)},onTimeout:e=>{this.emit(`serial:timeout`,e,this)}}),this.on(`serial:data`,()=>{this.queue.advance()}),t.register(this)}async handshake(){return!0}async connect(){if(!this.isConnecting&&!this.port){this.isConnecting=!0,this.emit(`serial:connecting`,this);try{let e=this.getSerial();if(!e)throw Error(`Web Serial API is not supported in this browser. Use AbstractSerialDevice.setProvider() to set a WebUSB polyfill.`);if(this.port=await this.findAndValidatePort(),!this.port){let t;try{t=await e.requestPort({filters:this.options.filters},this.options.polyfillOptions??r.polyfillOptions)}catch(e){throw e instanceof DOMException&&(e.name===`NotFoundError`||e.name===`SecurityError`||e.name===`AbortError`)?new i(e instanceof Error?e.message:String(e)):e instanceof Error?e:Error(String(e))}if(!await this.openAndHandshake(t))throw Error(`Handshake failed: the selected device did not respond correctly.`);this.port=t}this.abortController=new AbortController,this.queue.resume(),this.emit(`serial:connected`,this)}catch(e){if(e instanceof i?this.emit(`serial:need-permission`,this):this.emit(`serial:error`,e instanceof Error?e:Error(String(e)),this),this.port){t.unlockPort(this.port);try{await this.port.close()}catch{}this.port=null}throw e}finally{this.isConnecting=!1}}}async disconnect(){this.port&&(this.userInitiatedDisconnect=!0,this.stopReconnecting(),await this.cleanupPort())}isConnected(){return!!(this.port&&this.port.connected&&this.port.readable&&this.port.writable)}isDisconnected(){return!this.isConnected()}async cleanupPort(){if(this.port){this.queue.pause(),this.abortController?.abort(),this.abortController=null;try{let e=this.reader,t=this.writer;if(this.reader=null,this.writer=null,e){try{await e.cancel()}catch{}try{e.releaseLock()}catch{}}if(t){try{await t.close()}catch{}try{t.releaseLock()}catch{}}try{await this.port.close()}catch{}}catch(e){this.emit(`serial:error`,e instanceof Error?e:Error(String(e)),this)}finally{this.port&&t.unlockPort(this.port),this.port=null,this.options.parser?.reset?.(),this.emit(`serial:disconnected`,this),!this.userInitiatedDisconnect&&this.options.autoReconnect&&this.startReconnecting(),this.userInitiatedDisconnect=!1}}}async forget(){await this.disconnect(),this.port&&typeof this.port.forget==`function`&&await this.port.forget(),t.unregister(this)}async send(e){let t;t=typeof e==`string`?new TextEncoder().encode(e):e,t.length>0&&this.queue.enqueue(t)}clearQueue(){this.queue.clear(),this.emit(`serial:queue-empty`,this)}async writeToPort(e){if(!this.port||!this.port.writable)throw new s(`Port not writable.`);this.writer=this.port.writable.getWriter();try{await this.writer.write(e)}catch(e){throw new s(e instanceof Error?e.message:String(e))}finally{this.writer.releaseLock(),this.writer=null}}async readLoop(){if(!(!this.port||!this.port.readable)&&!this.reader){this.reader=this.port.readable.getReader();try{for(;;){let{value:e,done:t}=await this.reader.read();if(t)break;e&&(this.options.parser?this.options.parser.parse(e,e=>{this.emit(`serial:data`,e,this)}):this.emit(`serial:data`,e,this))}}catch(e){if(this.port)throw new o(e instanceof Error?e.message:String(e))}finally{if(this.reader){try{this.reader.releaseLock()}catch{}this.reader=null}}}}async openAndHandshake(e){let n=this;if(t.isPortInUse(e,n))return!1;t.lockPort(e,n);try{await e.open({baudRate:this.options.baudRate,dataBits:this.options.dataBits,stopBits:this.options.stopBits,parity:this.options.parity,bufferSize:this.options.bufferSize,flowControl:this.options.flowControl})}catch(n){throw t.unlockPort(e),n instanceof Error?n:Error(String(n))}this.port=e,this.abortController=new AbortController;let r=this.queue.snapshot();this.isHandshaking=!0,this.readLoop().catch(e=>{!this.isHandshaking&&this.port&&(this.emit(`serial:error`,e,this),this.cleanupPort())}),this.queue.resume();try{let t=await this.runHandshakeWithTimeout();return this.isHandshaking=!1,t?(this.queue.pause(),this.queue.clear(),this.queue.restore(r),this.options.parser?.reset?.(),!0):(await this.teardownHandshake(e,r),!1)}catch{return this.isHandshaking=!1,await this.teardownHandshake(e,r),!1}}async teardownHandshake(e,n){this.queue.pause(),this.queue.clear(),this.queue.restore(n),await this.stopReader(),this.port=null,this.abortController=null,this.options.parser?.reset?.();try{await e.close()}catch{}t.unlockPort(e)}async stopReader(){let e=this.reader;if(this.reader=null,e){try{await e.cancel()}catch{}try{e.releaseLock()}catch{}}}async runHandshakeWithTimeout(){let e=this.options.handshakeTimeout??2e3;return Promise.race([this.handshake(),new Promise(t=>setTimeout(()=>t(!1),e))])}async findAndValidatePort(){let e=this.getSerial();if(!e)return null;let n=await e.getPorts(this.options.polyfillOptions??r.polyfillOptions);if(n.length===0)return null;let i=this.options.filters??[],a=this;for(let e of n)if(!t.isPortInUse(e,a)){if(i.length>0){let t=e.getInfo();if(!i.some(e=>{let n=e.usbVendorId===void 0||e.usbVendorId===t.usbVendorId,r=e.usbProductId===void 0||e.usbProductId===t.usbProductId;return n&&r}))continue}try{if(await this.openAndHandshake(e))return e}catch{}}return null}startReconnecting(){this.reconnectTimerId||=(this.emit(`serial:reconnecting`,this),setInterval(async()=>{if(this.port||this.isConnecting){this.stopReconnecting();return}try{let e=await this.findAndValidatePort();e&&(this.stopReconnecting(),await this.reconnect(e))}catch{}},this.options.autoReconnectInterval))}stopReconnecting(){this.reconnectTimerId&&=(clearInterval(this.reconnectTimerId),null)}async reconnect(e){if(!(this.isConnecting||this.port)){this.isConnecting=!0,this.emit(`serial:connecting`,this);try{this.port=e,this.abortController=new AbortController,this.queue.resume(),this.emit(`serial:connected`,this)}catch(e){this.emit(`serial:error`,e instanceof Error?e:Error(String(e)),this),this.port&&=(t.unlockPort(this.port),null),this.options.autoReconnect&&this.startReconnecting()}finally{this.isConnecting=!1}}}static getInstances(){return t.getInstances()}static async connectAll(){let e=t.getInstances();for(let t of e)try{await t.connect()}catch{}}static setProvider(e,t){r.customProvider=e,r.polyfillOptions=t}getSerial(){return this.options.provider?this.options.provider:r.customProvider?r.customProvider:typeof navigator<`u`&&navigator.serial?navigator.serial:null}};function l(e){if(e<=0)throw Error(`FixedLengthParser: length must be greater than 0`);let t=new Uint8Array;return{parse(n,r){let i=new Uint8Array(t.length+n.length);for(i.set(t),i.set(n,t.length),t=i;t.length>=e;)r(t.slice(0,e)),t=t.slice(e)},reset(){t=new Uint8Array}}}function u(e){let t=``,n=new TextDecoder;return{parse(r,i){t+=n.decode(r,{stream:!0});let a;for(;(a=t.indexOf(e))!==-1;)i(t.slice(0,a)),t=t.slice(a+e.length)},reset(){t=``,n=new TextDecoder}}}function d(){return{parse(e,t){t(e)},reset(){}}}var f=32,p=34,m=0,h=30,g=3,_=7,v=1,y=0,b=771,x=768,S=255,C=8,w=`none`,T=1,E=[16,8,7,6,5],D=[1,2],O=[`none`,`even`,`odd`],k=[`none`,`odd`,`even`],A=[1,1.5,2],j={usbControlInterfaceClass:2,usbTransferInterfaceClass:10,protocol:void 0};function M(e,t){let n=e.configurations[0];if(!n)return null;for(let e of n.interfaces)if(e.alternates[0]?.interfaceClass===t)return e;return null}function N(e,t){let n=e.configurations[0];if(!n)return null;for(let e of n.interfaces){let n=e.alternates[0];if(!n||n.interfaceClass!==t)continue;let r=n.endpoints.some(e=>e.direction===`in`),i=n.endpoints.some(e=>e.direction===`out`);if(r&&i)return e}return null}function P(e,t){let n=e.alternates[0];if(n){for(let e of n.endpoints)if(e.direction===t)return e}throw TypeError(`Interface ${e.interfaceNumber} does not have an ${t} endpoint.`)}function F(e,t){return t===2?`cdc_acm`:e.vendorId===4292?`cp210x`:`none`}var I=class{device_;endpoint_;onError_;constructor(e,t,n){this.device_=e,this.endpoint_=t,this.onError_=n}pull(e){(async()=>{let t=this.endpoint_.packetSize;try{let n=await this.device_.transferIn(this.endpoint_.endpointNumber,t);if(n.status!==`ok`){e.error(`USB error: ${n.status}`),this.onError_();return}if(n.data?.buffer&&n.data.byteLength>0){let t=new Uint8Array(n.data.buffer,n.data.byteOffset,n.data.byteLength);t.length>0&&e.enqueue(t)}}catch(t){e.error(String(t)),this.onError_()}})()}},L=class{device_;endpoint_;onError_;constructor(e,t,n){this.device_=e,this.endpoint_=t,this.onError_=n}async write(e,t){try{let n=await this.device_.transferOut(this.endpoint_.endpointNumber,e.buffer);n.status!==`ok`&&(t.error(n.status),this.onError_())}catch(e){t.error(String(e)),this.onError_()}}},R=class{device_;protocol_;controlInterface_;transferInterface_;inEndpoint_;outEndpoint_;serialOptions_;readable_=null;writable_=null;cdcOutputSignals_={dataTerminalReady:!1,requestToSend:!1,break:!1};constructor(e,t){this.device_=e;let n={...j,...t};this.protocol_=n.protocol??F(e,n.usbControlInterfaceClass);let r=n.usbControlInterfaceClass,i=n.usbTransferInterfaceClass;if(r===i){let t=N(e,i);if(!t)throw TypeError(`Unable to find interface with class ${i} that has both IN and OUT endpoints.`);this.controlInterface_=t,this.transferInterface_=t}else{let t=M(e,r);if(!t)throw TypeError(`Unable to find control interface with class ${r}.`);let n=N(e,i)??M(e,i);if(!n)throw TypeError(`Unable to find transfer interface with class ${i}.`);this.controlInterface_=t,this.transferInterface_=n}this.inEndpoint_=P(this.transferInterface_,`in`),this.outEndpoint_=P(this.transferInterface_,`out`)}get readable(){return!this.readable_&&this.device_.opened&&(this.readable_=new ReadableStream(new I(this.device_,this.inEndpoint_,()=>{this.readable_=null}),{highWaterMark:this.serialOptions_?.bufferSize??S})),this.readable_}get writable(){return!this.writable_&&this.device_.opened&&(this.writable_=new WritableStream(new L(this.device_,this.outEndpoint_,()=>{this.writable_=null}),new ByteLengthQueuingStrategy({highWaterMark:this.serialOptions_?.bufferSize??S}))),this.writable_}async open(e){this.serialOptions_=e,this.validateOptions();try{switch(await this.device_.open(),this.device_.configuration===null&&await this.device_.selectConfiguration(1),await this.device_.claimInterface(this.controlInterface_.interfaceNumber),this.controlInterface_!==this.transferInterface_&&await this.device_.claimInterface(this.transferInterface_.interfaceNumber),this.protocol_){case`cdc_acm`:await this.cdcInit();break;case`cp210x`:await this.cp210xInit();break;case`none`:break}}catch(e){throw this.device_.opened&&await this.device_.close(),Error(`Error setting up device: `+(e instanceof Error?e.message:String(e)),{cause:e})}}async close(){let e=[];if(this.readable_&&e.push(this.readable_.cancel()),this.writable_&&e.push(this.writable_.abort()),await Promise.all(e),this.readable_=null,this.writable_=null,this.device_.opened){switch(this.protocol_){case`cdc_acm`:await this.cdcSetSignals({dataTerminalReady:!1,requestToSend:!1});break;case`cp210x`:await this.cp210xDeinit();break}await this.device_.close()}}async forget(){return this.device_.forget()}getInfo(){return{usbVendorId:this.device_.vendorId,usbProductId:this.device_.productId}}async cdcInit(){await this.cdcSetLineCoding(),await this.cdcSetSignals({dataTerminalReady:!0})}async cdcSetSignals(e){if(this.cdcOutputSignals_={...this.cdcOutputSignals_,...e},e.dataTerminalReady!==void 0||e.requestToSend!==void 0){let e=!!this.cdcOutputSignals_.dataTerminalReady|(this.cdcOutputSignals_.requestToSend?2:0);await this.device_.controlTransferOut({requestType:`class`,recipient:`interface`,request:p,value:e,index:this.controlInterface_.interfaceNumber})}}async cdcSetLineCoding(){let e=new ArrayBuffer(7),t=new DataView(e);if(t.setUint32(0,this.serialOptions_.baudRate,!0),t.setUint8(4,A.indexOf(this.serialOptions_.stopBits??T)),t.setUint8(5,k.indexOf(this.serialOptions_.parity??w)),t.setUint8(6,this.serialOptions_.dataBits??C),(await this.device_.controlTransferOut({requestType:`class`,recipient:`interface`,request:f,value:0,index:this.controlInterface_.interfaceNumber},e)).status!==`ok`)throw new DOMException(`Failed to set line coding.`,`NetworkError`)}async cp210xInit(){let e=this.controlInterface_.interfaceNumber;await this.device_.controlTransferOut({requestType:`vendor`,recipient:`interface`,request:m,value:v,index:e});let t=new ArrayBuffer(4);new DataView(t).setUint32(0,this.serialOptions_.baudRate,!0),await this.device_.controlTransferOut({requestType:`vendor`,recipient:`interface`,request:h,value:0,index:e},t);let n=this.serialOptions_.dataBits??C,r={none:0,odd:16,even:32}[this.serialOptions_.parity??w]??0,i=({1:0,2:2}[this.serialOptions_.stopBits??T]??0)<<8|r|n;await this.device_.controlTransferOut({requestType:`vendor`,recipient:`interface`,request:g,value:i,index:e}),await this.device_.controlTransferOut({requestType:`vendor`,recipient:`interface`,request:_,value:b,index:e})}async cp210xDeinit(){let e=this.controlInterface_.interfaceNumber;await this.device_.controlTransferOut({requestType:`vendor`,recipient:`interface`,request:_,value:x,index:e}),await this.device_.controlTransferOut({requestType:`vendor`,recipient:`interface`,request:m,value:y,index:e})}validateOptions(){if(this.serialOptions_.baudRate%1!=0)throw RangeError(`Invalid baud rate: ${this.serialOptions_.baudRate}`);if(this.serialOptions_.dataBits!==void 0&&!E.includes(this.serialOptions_.dataBits))throw RangeError(`Invalid dataBits: ${this.serialOptions_.dataBits}`);if(this.serialOptions_.stopBits!==void 0&&!D.includes(this.serialOptions_.stopBits))throw RangeError(`Invalid stopBits: ${this.serialOptions_.stopBits}`);if(this.serialOptions_.parity!==void 0&&!O.includes(this.serialOptions_.parity))throw RangeError(`Invalid parity: ${this.serialOptions_.parity}`)}},z=class{options_;constructor(e){this.options_={...j,...e}}async requestPort(e,t){let n={...this.options_,...t},r=[];if(e?.filters&&e.filters.length>0)for(let t of e.filters){let e={};t.usbVendorId!==void 0&&(e.vendorId=t.usbVendorId),t.usbProductId!==void 0&&(e.productId=t.usbProductId),n.usbControlInterfaceClass!==void 0&&n.usbControlInterfaceClass!==255?e.classCode=n.usbControlInterfaceClass:e.vendorId===void 0&&e.productId===void 0&&(e.classCode=n.usbControlInterfaceClass??2),r.push(e)}else r.push({classCode:n.usbControlInterfaceClass??2});return new R(await navigator.usb.requestDevice({filters:r}),n)}async getPorts(e){let t={...this.options_,...e},n=await navigator.usb.getDevices(),r=[];for(let e of n)try{let n=new R(e,t);r.push(n)}catch{}return r}},B=`6e400001-b5a3-f393-e0a9-e50e24dcca9e`,V=`6e400003-b5a3-f393-e0a9-e50e24dcca9e`,H=`6e400002-b5a3-f393-e0a9-e50e24dcca9e`,U=20,W=10;function G(e){let t=null,n=null,r=null;return{get readable(){return t},get writable(){return n},getInfo(){return{}},async open(){if(!e.gatt)throw Error(`GATT not available on this Bluetooth device.`);r=await e.gatt.connect();let i=await r.getPrimaryService(B),a=await i.getCharacteristic(V),o=await i.getCharacteristic(H);await a.startNotifications(),t=new ReadableStream({start(e){a.addEventListener(`characteristicvaluechanged`,t=>{let n=t.target.value.buffer;e.enqueue(new Uint8Array(n))})}}),n=new WritableStream({async write(e){for(let t=0;t<e.length;t+=U){let n=e.slice(t,t+U);await o.writeValueWithoutResponse(n),t+U<e.length&&await new Promise(e=>setTimeout(e,W))}}})},async close(){r?.connected&&r.disconnect(),t=null,n=null}}}function K(){return{async requestPort(){if(!navigator.bluetooth)throw Error(`Web Bluetooth API is not supported in this browser. Use Chrome on Android, macOS, or ChromeOS.`);return G(await navigator.bluetooth.requestDevice({filters:[{services:[B]}]}))},async getPorts(){return[]}}}function q(e){return new Promise((t,n)=>{e.addEventListener(`open`,()=>t(),{once:!0}),e.addEventListener(`error`,e=>n(e),{once:!0})})}function J(e,t){return new Promise(n=>{let r=i=>{let a=JSON.parse(i.data);a.type===t&&(e.removeEventListener(`message`,r),n(a.payload))};e.addEventListener(`message`,r)})}function Y(e,t){let n=null,r=null;return{get readable(){return n},get writable(){return r},getInfo(){return{usbVendorId:t.vendorId,usbProductId:t.productId}},async open(i){e.send(JSON.stringify({type:`open`,path:t.path,baudRate:i.baudRate,dataBits:i.dataBits,stopBits:i.stopBits,parity:i.parity,parser:{type:`delimiter`,value:`\\n`}})),await J(e,`opened`);let a=[],o=null,s=!1;function c(e){let t=JSON.parse(e.data);if(t.type===`data`&&t.bytes){let e=new Uint8Array(t.bytes);o?o.enqueue(e):a.push(e)}t.type===`closed`&&(s=!0,o&&o.close())}e.addEventListener(`message`,c),n=new ReadableStream({start(e){o=e;for(let t of a)e.enqueue(t);a.length=0,s&&e.close()},cancel(){e.removeEventListener(`message`,c),o=null}}),r=new WritableStream({write(t){e.send(JSON.stringify({type:`write`,bytes:Array.from(t)}))}})},async close(){e.send(JSON.stringify({type:`close`})),n=null,r=null,e.close()}}}function X(e){return{async requestPort(t){let n=new WebSocket(e);await q(n),n.send(JSON.stringify({type:`list-ports`,filters:t?.filters??[]}));let r=(await J(n,`port-list`))[0];if(!r)throw Error(`No ports available on the bridge server. Make sure the Node.js server is running and a device is connected.`);return Y(n,r)},async getPorts(){let t=new WebSocket(e);return await q(t),t.send(JSON.stringify({type:`list-ports`,filters:[]})),(await J(t,`port-list`)).map(e=>Y(t,e))}}}exports.AbstractSerialDevice=c,exports.CommandQueue=n,exports.SerialEventEmitter=e,exports.SerialPermissionError=i,exports.SerialPortConflictError=r,exports.SerialReadError=o,exports.SerialRegistry=t,exports.SerialTimeoutError=a,exports.SerialWriteError=s,exports.WebUsbProvider=z,exports.createBluetoothProvider=K,exports.createWebSocketProvider=X,exports.delimiter=u,exports.fixedLength=l,exports.raw=d;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=class{listeners={};on(e,t){return this.listeners[e]||(this.listeners[e]=new Set),this.listeners[e].add(t),this}off(e,t){return this.listeners[e]&&this.listeners[e].delete(t),this}emit(e,...t){let n=this.listeners[e];if(!n||n.size===0)return!1;for(let e of n)e(...t);return!0}},t=class{static instances=new Set;static portInstanceMap=new WeakMap;static getInstances(){return Array.from(this.instances)}static register(e){this.instances.add(e)}static unregister(e){this.instances.delete(e)}static isPortInUse(e,t){let n=this.portInstanceMap.get(e);return n!==void 0&&n!==t}static lockPort(e,t){this.portInstanceMap.set(e,t)}static unlockPort(e){this.portInstanceMap.delete(e)}},n=class{queue=[];isProcessing=!1;isPaused=!0;timeoutId=null;commandTimeout;onSend;onTimeout;constructor(e){this.commandTimeout=e.commandTimeout,this.onSend=e.onSend,this.onTimeout=e.onTimeout}get queueSize(){return this.queue.length}enqueue(e){this.queue.push(e),this.tryProcessNext()}advance(){this.clearCommandTimeout(),this.isProcessing=!1,this.tryProcessNext()}pause(){this.isPaused=!0,this.clearCommandTimeout(),this.isProcessing=!1}resume(){this.isPaused=!1,this.tryProcessNext()}clear(){this.queue=[],this.clearCommandTimeout(),this.isProcessing=!1}snapshot(){return[...this.queue]}restore(e){this.queue=[...e,...this.queue]}tryProcessNext(){if(this.isPaused||this.isProcessing||this.queue.length===0)return;this.isProcessing=!0;let e=this.queue.shift();this.commandTimeout>0&&(this.timeoutId=setTimeout(()=>{this.timeoutId=null,this.onTimeout(e),this.advance()},this.commandTimeout)),this.onSend(e).catch(()=>{this.advance()})}clearCommandTimeout(){this.timeoutId!==null&&(clearTimeout(this.timeoutId),this.timeoutId=null)}},r=class e extends Error{constructor(t){super(t),this.name=`SerialPortConflictError`,Object.setPrototypeOf(this,e.prototype)}},i=class e extends Error{constructor(t){super(t),this.name=`SerialPermissionError`,Object.setPrototypeOf(this,e.prototype)}},a=class e extends Error{constructor(t){super(t),this.name=`SerialTimeoutError`,Object.setPrototypeOf(this,e.prototype)}},o=class e extends Error{constructor(t){super(t),this.name=`SerialReadError`,Object.setPrototypeOf(this,e.prototype)}},s=class e extends Error{constructor(t){super(t),this.name=`SerialWriteError`,Object.setPrototypeOf(this,e.prototype)}},c=class r extends e{port=null;reader=null;writer=null;queue;options;isConnecting=!1;abortController=null;userInitiatedDisconnect=!1;reconnectTimerId=null;isHandshaking=!1;static customProvider=null;static polyfillOptions;constructor(e){super(),this.options={baudRate:e.baudRate,dataBits:e.dataBits??8,stopBits:e.stopBits??1,parity:e.parity??`none`,bufferSize:e.bufferSize??255,flowControl:e.flowControl??`none`,filters:e.filters??[],commandTimeout:e.commandTimeout??0,parser:e.parser,autoReconnect:e.autoReconnect??!1,autoReconnectInterval:e.autoReconnectInterval??1500,handshakeTimeout:e.handshakeTimeout??2e3,provider:e.provider,polyfillOptions:e.polyfillOptions},this.queue=new n({commandTimeout:this.options.commandTimeout,onSend:async e=>{await this.writeToPort(e),this.emit(`serial:sent`,e,this)},onTimeout:e=>{this.emit(`serial:timeout`,e,this)}}),this.on(`serial:data`,()=>{this.queue.advance()}),t.register(this)}async handshake(){return!0}async connect(){if(!this.isConnecting&&!this.port){this.isConnecting=!0,this.emit(`serial:connecting`,this);try{let e=this.getSerial();if(!e)throw Error(`Web Serial API is not supported in this browser. Use AbstractSerialDevice.setProvider() to set a WebUSB polyfill.`);if(this.port=await this.findAndValidatePort(),!this.port){let t;try{t=await e.requestPort({filters:this.options.filters},this.options.polyfillOptions??r.polyfillOptions)}catch(e){throw e instanceof DOMException&&(e.name===`NotFoundError`||e.name===`SecurityError`||e.name===`AbortError`)?new i(e instanceof Error?e.message:String(e)):e instanceof Error?e:Error(String(e))}if(!await this.openAndHandshake(t))throw Error(`Handshake failed: the selected device did not respond correctly.`);this.port=t}this.abortController=new AbortController,this.queue.resume(),this.emit(`serial:connected`,this)}catch(e){if(e instanceof i?this.emit(`serial:need-permission`,this):this.emit(`serial:error`,e instanceof Error?e:Error(String(e)),this),this.port){t.unlockPort(this.port);try{await this.port.close()}catch{}this.port=null}throw e}finally{this.isConnecting=!1}}}async disconnect(){this.port&&(this.userInitiatedDisconnect=!0,this.stopReconnecting(),await this.cleanupPort())}isConnected(){return!!(this.port&&this.port.connected&&this.port.readable&&this.port.writable)}isDisconnected(){return!this.isConnected()}async cleanupPort(){if(this.port){this.queue.pause(),this.abortController?.abort(),this.abortController=null;try{let e=this.reader,t=this.writer;if(this.reader=null,this.writer=null,e){try{await e.cancel()}catch{}try{e.releaseLock()}catch{}}if(t){try{await t.close()}catch{}try{t.releaseLock()}catch{}}try{await this.port.close()}catch{}}catch(e){this.emit(`serial:error`,e instanceof Error?e:Error(String(e)),this)}finally{this.port&&t.unlockPort(this.port),this.port=null,this.options.parser?.reset?.(),this.emit(`serial:disconnected`,this),!this.userInitiatedDisconnect&&this.options.autoReconnect&&this.startReconnecting(),this.userInitiatedDisconnect=!1}}}async forget(){await this.disconnect(),this.port&&typeof this.port.forget==`function`&&await this.port.forget(),t.unregister(this)}async send(e){let t;t=typeof e==`string`?new TextEncoder().encode(e):e,t.length>0&&this.queue.enqueue(t)}clearQueue(){this.queue.clear(),this.emit(`serial:queue-empty`,this)}async writeToPort(e){if(!this.port||!this.port.writable)throw new s(`Port not writable.`);this.writer=this.port.writable.getWriter();try{await this.writer.write(e)}catch(e){throw new s(e instanceof Error?e.message:String(e))}finally{this.writer.releaseLock(),this.writer=null}}async readLoop(){if(!(!this.port||!this.port.readable)&&!this.reader){this.reader=this.port.readable.getReader();try{for(;;){let{value:e,done:t}=await this.reader.read();if(t)break;e&&(this.options.parser?this.options.parser.parse(e,e=>{this.emit(`serial:data`,e,this)}):this.emit(`serial:data`,e,this))}}catch(e){if(this.port)throw new o(e instanceof Error?e.message:String(e))}finally{if(this.reader){try{this.reader.releaseLock()}catch{}this.reader=null}}}}async openAndHandshake(e){let n=this;if(t.isPortInUse(e,n))return!1;t.lockPort(e,n);try{await e.open({baudRate:this.options.baudRate,dataBits:this.options.dataBits,stopBits:this.options.stopBits,parity:this.options.parity,bufferSize:this.options.bufferSize,flowControl:this.options.flowControl})}catch(n){throw t.unlockPort(e),n instanceof Error?n:Error(String(n))}this.port=e,this.abortController=new AbortController;let r=this.queue.snapshot();this.isHandshaking=!0,this.readLoop().catch(e=>{!this.isHandshaking&&this.port&&(this.emit(`serial:error`,e,this),this.cleanupPort())}),this.queue.resume();try{let t=await this.runHandshakeWithTimeout();return this.isHandshaking=!1,t?(this.queue.pause(),this.queue.clear(),this.queue.restore(r),this.options.parser?.reset?.(),!0):(await this.teardownHandshake(e,r),!1)}catch{return this.isHandshaking=!1,await this.teardownHandshake(e,r),!1}}async teardownHandshake(e,n){this.queue.pause(),this.queue.clear(),this.queue.restore(n),await this.stopReader(),this.port=null,this.abortController=null,this.options.parser?.reset?.();try{await e.close()}catch{}t.unlockPort(e)}async stopReader(){let e=this.reader;if(this.reader=null,e){try{await e.cancel()}catch{}try{e.releaseLock()}catch{}}}async runHandshakeWithTimeout(){let e=this.options.handshakeTimeout??2e3;return Promise.race([this.handshake(),new Promise(t=>setTimeout(()=>t(!1),e))])}async findAndValidatePort(){let e=this.getSerial();if(!e)return null;let n=await e.getPorts(this.options.polyfillOptions??r.polyfillOptions);if(n.length===0)return null;let i=this.options.filters??[],a=this;for(let e of n)if(!t.isPortInUse(e,a)){if(i.length>0){let t=e.getInfo();if(!i.some(e=>{let n=e.usbVendorId===void 0||e.usbVendorId===t.usbVendorId,r=e.usbProductId===void 0||e.usbProductId===t.usbProductId;return n&&r}))continue}try{if(await this.openAndHandshake(e))return e}catch{}}return null}startReconnecting(){this.reconnectTimerId||=(this.emit(`serial:reconnecting`,this),setInterval(async()=>{if(this.port||this.isConnecting){this.stopReconnecting();return}try{let e=await this.findAndValidatePort();e&&(this.stopReconnecting(),await this.reconnect(e))}catch{}},this.options.autoReconnectInterval))}stopReconnecting(){this.reconnectTimerId&&=(clearInterval(this.reconnectTimerId),null)}async reconnect(e){if(!(this.isConnecting||this.port)){this.isConnecting=!0,this.emit(`serial:connecting`,this);try{this.port=e,this.abortController=new AbortController,this.queue.resume(),this.emit(`serial:connected`,this)}catch(e){this.emit(`serial:error`,e instanceof Error?e:Error(String(e)),this),this.port&&=(t.unlockPort(this.port),null),this.options.autoReconnect&&this.startReconnecting()}finally{this.isConnecting=!1}}}static getInstances(){return t.getInstances()}static async connectAll(){let e=t.getInstances();for(let t of e)try{await t.connect()}catch{}}static setProvider(e,t){r.customProvider=e,r.polyfillOptions=t}getSerial(){return this.options.provider?this.options.provider:r.customProvider?r.customProvider:typeof navigator<`u`&&navigator.serial?navigator.serial:null}};function l(e=50){let t=new Uint8Array,n=null;function r(e){for(;!(t.length<2);){let n=t[1]+5;if(t.length<n)break;e(t.slice(0,n)),t=t.slice(n)}}return{parse(i,a){n!==null&&(clearTimeout(n),n=null);let o=new Uint8Array(t.length+i.length);o.set(t),o.set(i,t.length),t=o,r(a),t.length>0&&(n=setTimeout(()=>{t=new Uint8Array,n=null},e))},reset(){n!==null&&(clearTimeout(n),n=null),t=new Uint8Array}}}function u(e){return typeof e==`string`?new TextEncoder().encode(e):e instanceof Uint8Array?e:new Uint8Array(e)}function d(e,t){if(t.length===0)return 0;outer:for(let n=0;n<=e.length-t.length;n++){for(let r=0;r<t.length;r++)if(e[n+r]!==t[r])continue outer;return n}return-1}function f(e,t){let n=t?.includeDelimiter??!1,r=u(e);if(typeof e==`string`){let e=new Uint8Array,t=new TextDecoder;return{parse(i,a){let o=new Uint8Array(e.length+i.length);o.set(e),o.set(i,e.length),e=o;let s;for(;(s=d(e,r))!==-1;){let i=n?s+r.length:s;a(t.decode(e.slice(0,i))),t=new TextDecoder,e=e.slice(s+r.length)}},reset(){e=new Uint8Array,t=new TextDecoder}}}let i=new Uint8Array;return{parse(e,t){let a=new Uint8Array(i.length+e.length);a.set(i),a.set(e,i.length),i=a;let o;for(;(o=d(i,r))!==-1;){let e=n?o+r.length:o;t(i.slice(0,e)),i=i.slice(o+r.length)}},reset(){i=new Uint8Array}}}function p(e){if(e<=0)throw Error(`FixedLengthParser: length must be greater than 0`);let t=new Uint8Array;return{parse(n,r){let i=new Uint8Array(t.length+n.length);for(i.set(t),i.set(n,t.length),t=i;t.length>=e;)r(t.slice(0,e)),t=t.slice(e)},reset(){t=new Uint8Array}}}function m(e){if(e.interval<=0)throw Error(`InterByteTimeoutParser: interval must be greater than 0`);let t=e.maxBufferSize??65536,n=new Uint8Array,r=null,i=null;function a(){r!==null&&(clearTimeout(r),r=null),n.length>0&&i!==null&&(i(n.slice()),n=new Uint8Array)}return{parse(o,s){i=s,r!==null&&(clearTimeout(r),r=null);let c=new Uint8Array(n.length+o.length);if(c.set(n),c.set(o,n.length),n=c,n.length>=t){a();return}r=setTimeout(()=>{r=null,a()},e.interval)},reset(){r!==null&&(clearTimeout(r),r=null),n=new Uint8Array,i=null}}}function h(e){let t=e?.delimiter??170,n=e?.packetOverhead??2,r=e?.lengthBytes??1,i=e?.lengthOffset??1,a=e?.maxLen??255;if(i+r>n)throw Error(`PacketLengthParser: lengthOffset + lengthBytes must not exceed packetOverhead`);let o=new Uint8Array;return{parse(e,s){let c=new Uint8Array(o.length+e.length);for(c.set(o),c.set(e,o.length),o=c;;){let e=o.indexOf(t);if(e===-1){o=new Uint8Array;break}e>0&&(o=o.slice(e));let c=i+r;if(o.length<c)break;let l=0;for(let e=0;e<r;e++)l=l<<8|o[i+e];if(l>a){o=o.slice(1);continue}let u=l+n;if(o.length<u)break;s(o.slice(0,u)),o=o.slice(u)}},reset(){o=new Uint8Array}}}function g(){return{parse(e,t){t(e)},reset(){}}}function _(e,t){if(t.length===0)return 0;outer:for(let n=0;n<=e.length-t.length;n++){for(let r=0;r<t.length;r++)if(e[n+r]!==t[r])continue outer;return n}return-1}function v(e){let t=e?.encoding??`utf-8`,n=e?.includeDelimiter??!1,r=e?.delimiter??`
2
+ `,i;i=typeof r==`string`?new TextEncoder().encode(r):r instanceof Uint8Array?r:new Uint8Array(r);let a=new Uint8Array;return{parse(e,r){let o=new Uint8Array(a.length+e.length);o.set(a),o.set(e,a.length),a=o;let s;for(;(s=_(a,i))!==-1;){let e=n?s+i.length:s;r(new TextDecoder(t).decode(a.slice(0,e))),a=a.slice(s+i.length)}},reset(){a=new Uint8Array}}}function y(e,t){if(t.length===0)return 0;outer:for(let n=0;n<=e.length-t.length;n++){for(let r=0;r<t.length;r++)if(e[n+r]!==t[r])continue outer;return n}return-1}function b(e){let t=e.delimiter,n;n=typeof t==`string`?new TextEncoder().encode(t):t instanceof Uint8Array?t:new Uint8Array(t);let r=!1,i=new Uint8Array;return{parse(t,a){if(r){a(t);return}let o=new Uint8Array(i.length+t.length);o.set(i),o.set(t,i.length),i=o;let s=y(i,n);if(s===-1)return;r=!0,e.onReady?.();let c=i.slice(s+n.length);i=new Uint8Array,c.length>0&&a(c)},reset(){r=!1,i=new Uint8Array}}}function x(e){let t=e.regex instanceof RegExp?e.regex:new RegExp(e.regex),n=e.encoding??`utf-8`,r=``;return{parse(e,i){let a=new TextDecoder(n);r+=a.decode(e);let o=r.split(t);r=o.pop()??``;for(let e of o)i(e)},reset(){r=``}}}var S={END:192,ESC:219,ESC_END:220,ESC_ESC:221};function C(e){let t=e?.END??S.END,n=e?.ESC??S.ESC,r=e?.ESC_END??S.ESC_END,i=e?.ESC_ESC??S.ESC_ESC,a=e?.START,o=e?.ESC_START??n,s=[],c=!1,l=a===void 0;return{parse(e,u){for(let d=0;d<e.length;d++){let f=e[d];if(!l){f===a&&(l=!0);continue}if(f===t){s.length>0&&(u(new Uint8Array(s)),s=[]),a!==void 0&&(l=!1),c=!1;continue}if(c){c=!1,f===r?s.push(t):f===i?s.push(n):a!==void 0&&f===o?s.push(a):s.push(f);continue}if(f===n){c=!0;continue}s.push(f)}},reset(){s=[],c=!1,l=a===void 0}}}function ee(e,t){let n=t?.END??S.END,r=t?.ESC??S.ESC,i=t?.ESC_END??S.ESC_END,a=t?.ESC_ESC??S.ESC_ESC,o=t?.START,s=t?.ESC_START??r,c=t?.bluetoothQuirk??!1,l=[];c&&l.push(n);for(let t=0;t<e.length;t++){let c=e[t];c===n?l.push(r,i):c===r?l.push(r,a):o!==void 0&&c===o?l.push(r,s):l.push(c)}return l.push(n),new Uint8Array(l)}function te(e){let t=e?.timeCodeFieldLength??0,n=e?.ancillaryDataFieldLength??0,r=new Uint8Array;function i(e){let r=e[0],i=e[1],a=e[2],o=e[3],s=e[4],c=e[5],l=r>>5&7,u=r>>4&1,d=r>>3&1,f=(r&7)<<8|i,p=a>>6&3,m=(a&63)<<8|o,h=s<<8|c,g={versionNumber:l,identification:{apid:f,secondaryHeader:d,type:u},sequenceControl:{packetName:m,sequenceFlags:p},dataLength:h},_,v=6;if(d===1){_={};let r=new TextDecoder(`latin1`);t>0&&(_.timeCode=r.decode(e.slice(v,v+t)),v+=t),n>0&&(_.ancillaryData=r.decode(e.slice(v,v+n)),v+=n)}let y=new TextDecoder(`latin1`).decode(e.slice(v));return{header:g,secondaryHeader:_,data:y}}return{parse(e,t){let n=new Uint8Array(r.length+e.length);for(n.set(r),n.set(e,r.length),r=n;r.length>=6;){let e=6+(r[4]<<8|r[5])+1;if(r.length<e)break;t(i(r.slice(0,e))),r=r.slice(e)}},reset(){r=new Uint8Array}}}var w=32,T=34,E=0,D=30,O=3,k=7,A=1,ne=0,re=771,ie=768,j=255,M=8,N=`none`,P=1,F=[16,8,7,6,5],I=[1,2],L=[`none`,`even`,`odd`],R=[`none`,`odd`,`even`],z=[1,1.5,2],B={usbControlInterfaceClass:2,usbTransferInterfaceClass:10,protocol:void 0};function V(e,t){let n=e.configurations[0];if(!n)return null;for(let e of n.interfaces)if(e.alternates[0]?.interfaceClass===t)return e;return null}function H(e,t){let n=e.configurations[0];if(!n)return null;for(let e of n.interfaces){let n=e.alternates[0];if(!n||n.interfaceClass!==t)continue;let r=n.endpoints.some(e=>e.direction===`in`),i=n.endpoints.some(e=>e.direction===`out`);if(r&&i)return e}return null}function U(e,t){let n=e.alternates[0];if(n){for(let e of n.endpoints)if(e.direction===t)return e}throw TypeError(`Interface ${e.interfaceNumber} does not have an ${t} endpoint.`)}function W(e,t){return t===2?`cdc_acm`:e.vendorId===4292?`cp210x`:`none`}var G=class{device_;endpoint_;onError_;constructor(e,t,n){this.device_=e,this.endpoint_=t,this.onError_=n}pull(e){(async()=>{let t=this.endpoint_.packetSize;try{let n=await this.device_.transferIn(this.endpoint_.endpointNumber,t);if(n.status!==`ok`){e.error(`USB error: ${n.status}`),this.onError_();return}if(n.data?.buffer&&n.data.byteLength>0){let t=new Uint8Array(n.data.buffer,n.data.byteOffset,n.data.byteLength);t.length>0&&e.enqueue(t)}}catch(t){e.error(String(t)),this.onError_()}})()}},K=class{device_;endpoint_;onError_;constructor(e,t,n){this.device_=e,this.endpoint_=t,this.onError_=n}async write(e,t){try{let n=await this.device_.transferOut(this.endpoint_.endpointNumber,e.buffer);n.status!==`ok`&&(t.error(n.status),this.onError_())}catch(e){t.error(String(e)),this.onError_()}}},q=class{device_;protocol_;controlInterface_;transferInterface_;inEndpoint_;outEndpoint_;serialOptions_;readable_=null;writable_=null;cdcOutputSignals_={dataTerminalReady:!1,requestToSend:!1,break:!1};constructor(e,t){this.device_=e;let n={...B,...t};this.protocol_=n.protocol??W(e,n.usbControlInterfaceClass);let r=n.usbControlInterfaceClass,i=n.usbTransferInterfaceClass;if(r===i){let t=H(e,i);if(!t)throw TypeError(`Unable to find interface with class ${i} that has both IN and OUT endpoints.`);this.controlInterface_=t,this.transferInterface_=t}else{let t=V(e,r);if(!t)throw TypeError(`Unable to find control interface with class ${r}.`);let n=H(e,i)??V(e,i);if(!n)throw TypeError(`Unable to find transfer interface with class ${i}.`);this.controlInterface_=t,this.transferInterface_=n}this.inEndpoint_=U(this.transferInterface_,`in`),this.outEndpoint_=U(this.transferInterface_,`out`)}get readable(){return!this.readable_&&this.device_.opened&&(this.readable_=new ReadableStream(new G(this.device_,this.inEndpoint_,()=>{this.readable_=null}),{highWaterMark:this.serialOptions_?.bufferSize??j})),this.readable_}get writable(){return!this.writable_&&this.device_.opened&&(this.writable_=new WritableStream(new K(this.device_,this.outEndpoint_,()=>{this.writable_=null}),new ByteLengthQueuingStrategy({highWaterMark:this.serialOptions_?.bufferSize??j}))),this.writable_}async open(e){this.serialOptions_=e,this.validateOptions();try{switch(await this.device_.open(),this.device_.configuration===null&&await this.device_.selectConfiguration(1),await this.device_.claimInterface(this.controlInterface_.interfaceNumber),this.controlInterface_!==this.transferInterface_&&await this.device_.claimInterface(this.transferInterface_.interfaceNumber),this.protocol_){case`cdc_acm`:await this.cdcInit();break;case`cp210x`:await this.cp210xInit();break;case`none`:break}}catch(e){throw this.device_.opened&&await this.device_.close(),Error(`Error setting up device: `+(e instanceof Error?e.message:String(e)),{cause:e})}}async close(){let e=[];if(this.readable_&&e.push(this.readable_.cancel()),this.writable_&&e.push(this.writable_.abort()),await Promise.all(e),this.readable_=null,this.writable_=null,this.device_.opened){switch(this.protocol_){case`cdc_acm`:await this.cdcSetSignals({dataTerminalReady:!1,requestToSend:!1});break;case`cp210x`:await this.cp210xDeinit();break}await this.device_.close()}}async forget(){return this.device_.forget()}getInfo(){return{usbVendorId:this.device_.vendorId,usbProductId:this.device_.productId}}async cdcInit(){await this.cdcSetLineCoding(),await this.cdcSetSignals({dataTerminalReady:!0})}async cdcSetSignals(e){if(this.cdcOutputSignals_={...this.cdcOutputSignals_,...e},e.dataTerminalReady!==void 0||e.requestToSend!==void 0){let e=!!this.cdcOutputSignals_.dataTerminalReady|(this.cdcOutputSignals_.requestToSend?2:0);await this.device_.controlTransferOut({requestType:`class`,recipient:`interface`,request:T,value:e,index:this.controlInterface_.interfaceNumber})}}async cdcSetLineCoding(){let e=new ArrayBuffer(7),t=new DataView(e);if(t.setUint32(0,this.serialOptions_.baudRate,!0),t.setUint8(4,z.indexOf(this.serialOptions_.stopBits??P)),t.setUint8(5,R.indexOf(this.serialOptions_.parity??N)),t.setUint8(6,this.serialOptions_.dataBits??M),(await this.device_.controlTransferOut({requestType:`class`,recipient:`interface`,request:w,value:0,index:this.controlInterface_.interfaceNumber},e)).status!==`ok`)throw new DOMException(`Failed to set line coding.`,`NetworkError`)}async cp210xInit(){let e=this.controlInterface_.interfaceNumber;await this.device_.controlTransferOut({requestType:`vendor`,recipient:`interface`,request:E,value:A,index:e});let t=new ArrayBuffer(4);new DataView(t).setUint32(0,this.serialOptions_.baudRate,!0),await this.device_.controlTransferOut({requestType:`vendor`,recipient:`interface`,request:D,value:0,index:e},t);let n=this.serialOptions_.dataBits??M,r={none:0,odd:16,even:32}[this.serialOptions_.parity??N]??0,i=({1:0,2:2}[this.serialOptions_.stopBits??P]??0)<<8|r|n;await this.device_.controlTransferOut({requestType:`vendor`,recipient:`interface`,request:O,value:i,index:e}),await this.device_.controlTransferOut({requestType:`vendor`,recipient:`interface`,request:k,value:re,index:e})}async cp210xDeinit(){let e=this.controlInterface_.interfaceNumber;await this.device_.controlTransferOut({requestType:`vendor`,recipient:`interface`,request:k,value:ie,index:e}),await this.device_.controlTransferOut({requestType:`vendor`,recipient:`interface`,request:E,value:ne,index:e})}validateOptions(){if(this.serialOptions_.baudRate%1!=0)throw RangeError(`Invalid baud rate: ${this.serialOptions_.baudRate}`);if(this.serialOptions_.dataBits!==void 0&&!F.includes(this.serialOptions_.dataBits))throw RangeError(`Invalid dataBits: ${this.serialOptions_.dataBits}`);if(this.serialOptions_.stopBits!==void 0&&!I.includes(this.serialOptions_.stopBits))throw RangeError(`Invalid stopBits: ${this.serialOptions_.stopBits}`);if(this.serialOptions_.parity!==void 0&&!L.includes(this.serialOptions_.parity))throw RangeError(`Invalid parity: ${this.serialOptions_.parity}`)}},J=class{options_;constructor(e){this.options_={...B,...e}}async requestPort(e,t){let n={...this.options_,...t},r=[];if(e?.filters&&e.filters.length>0)for(let t of e.filters){let e={};t.usbVendorId!==void 0&&(e.vendorId=t.usbVendorId),t.usbProductId!==void 0&&(e.productId=t.usbProductId),n.usbControlInterfaceClass!==void 0&&n.usbControlInterfaceClass!==255?e.classCode=n.usbControlInterfaceClass:e.vendorId===void 0&&e.productId===void 0&&(e.classCode=n.usbControlInterfaceClass??2),r.push(e)}else r.push({classCode:n.usbControlInterfaceClass??2});return new q(await navigator.usb.requestDevice({filters:r}),n)}async getPorts(e){let t={...this.options_,...e},n=await navigator.usb.getDevices(),r=[];for(let e of n)try{let n=new q(e,t);r.push(n)}catch{}return r}},Y=`6e400001-b5a3-f393-e0a9-e50e24dcca9e`,ae=`6e400003-b5a3-f393-e0a9-e50e24dcca9e`,oe=`6e400002-b5a3-f393-e0a9-e50e24dcca9e`,X=20,se=10;function ce(e){let t=null,n=null,r=null;return{get readable(){return t},get writable(){return n},getInfo(){return{}},async open(){if(!e.gatt)throw Error(`GATT not available on this Bluetooth device.`);r=await e.gatt.connect();let i=await r.getPrimaryService(Y),a=await i.getCharacteristic(ae),o=await i.getCharacteristic(oe);await a.startNotifications(),t=new ReadableStream({start(e){a.addEventListener(`characteristicvaluechanged`,t=>{let n=t.target.value.buffer;e.enqueue(new Uint8Array(n))})}}),n=new WritableStream({async write(e){for(let t=0;t<e.length;t+=X){let n=e.slice(t,t+X);await o.writeValueWithoutResponse(n),t+X<e.length&&await new Promise(e=>setTimeout(e,se))}}})},async close(){r?.connected&&r.disconnect(),t=null,n=null}}}function le(){return{async requestPort(){if(!navigator.bluetooth)throw Error(`Web Bluetooth API is not supported in this browser. Use Chrome on Android, macOS, or ChromeOS.`);return ce(await navigator.bluetooth.requestDevice({filters:[{services:[Y]}]}))},async getPorts(){return[]}}}function Z(e){return new Promise((t,n)=>{e.addEventListener(`open`,()=>t(),{once:!0}),e.addEventListener(`error`,e=>n(e),{once:!0})})}function Q(e,t){return new Promise(n=>{let r=i=>{let a=JSON.parse(i.data);a.type===t&&(e.removeEventListener(`message`,r),n(a.payload))};e.addEventListener(`message`,r)})}function $(e,t){let n=null,r=null;return{get readable(){return n},get writable(){return r},getInfo(){return{usbVendorId:t.vendorId,usbProductId:t.productId}},async open(i){e.send(JSON.stringify({type:`open`,path:t.path,baudRate:i.baudRate,dataBits:i.dataBits,stopBits:i.stopBits,parity:i.parity,parser:{type:`delimiter`,value:`\\n`}})),await Q(e,`opened`);let a=[],o=null,s=!1;function c(e){let t=JSON.parse(e.data);if(t.type===`data`&&t.bytes){let e=new Uint8Array(t.bytes);o?o.enqueue(e):a.push(e)}t.type===`closed`&&(s=!0,o&&o.close())}e.addEventListener(`message`,c),n=new ReadableStream({start(e){o=e;for(let t of a)e.enqueue(t);a.length=0,s&&e.close()},cancel(){e.removeEventListener(`message`,c),o=null}}),r=new WritableStream({write(t){e.send(JSON.stringify({type:`write`,bytes:Array.from(t)}))}})},async close(){e.send(JSON.stringify({type:`close`})),n=null,r=null,e.close()}}}function ue(e){return{async requestPort(t){let n=new WebSocket(e);await Z(n),n.send(JSON.stringify({type:`list-ports`,filters:t?.filters??[]}));let r=(await Q(n,`port-list`))[0];if(!r)throw Error(`No ports available on the bridge server. Make sure the Node.js server is running and a device is connected.`);return $(n,r)},async getPorts(){let t=new WebSocket(e);return await Z(t),t.send(JSON.stringify({type:`list-ports`,filters:[]})),(await Q(t,`port-list`)).map(e=>$(t,e))}}}exports.AbstractSerialDevice=c,exports.CommandQueue=n,exports.SerialEventEmitter=e,exports.SerialPermissionError=i,exports.SerialPortConflictError=r,exports.SerialReadError=o,exports.SerialRegistry=t,exports.SerialTimeoutError=a,exports.SerialWriteError=s,exports.WebUsbProvider=J,exports.ccTalk=l,exports.createBluetoothProvider=le,exports.createWebSocketProvider=ue,exports.delimiter=f,exports.fixedLength=p,exports.interByteTimeout=m,exports.packetLength=h,exports.raw=g,exports.readline=v,exports.readyParser=b,exports.regexParser=x,exports.slipDecoder=C,exports.slipEncode=ee,exports.spacePacket=te;
@@ -376,8 +376,80 @@ var e = class {
376
376
  }
377
377
  };
378
378
  //#endregion
379
+ //#region src/parsers/CCTalkParser.ts
380
+ function l(e = 50) {
381
+ let t = new Uint8Array(), n = null;
382
+ function r(e) {
383
+ for (; !(t.length < 2);) {
384
+ let n = t[1] + 5;
385
+ if (t.length < n) break;
386
+ e(t.slice(0, n)), t = t.slice(n);
387
+ }
388
+ }
389
+ return {
390
+ parse(i, a) {
391
+ n !== null && (clearTimeout(n), n = null);
392
+ let o = new Uint8Array(t.length + i.length);
393
+ o.set(t), o.set(i, t.length), t = o, r(a), t.length > 0 && (n = setTimeout(() => {
394
+ t = new Uint8Array(), n = null;
395
+ }, e));
396
+ },
397
+ reset() {
398
+ n !== null && (clearTimeout(n), n = null), t = new Uint8Array();
399
+ }
400
+ };
401
+ }
402
+ //#endregion
403
+ //#region src/parsers/DelimiterParser.ts
404
+ function u(e) {
405
+ return typeof e == "string" ? new TextEncoder().encode(e) : e instanceof Uint8Array ? e : new Uint8Array(e);
406
+ }
407
+ function d(e, t) {
408
+ if (t.length === 0) return 0;
409
+ outer: for (let n = 0; n <= e.length - t.length; n++) {
410
+ for (let r = 0; r < t.length; r++) if (e[n + r] !== t[r]) continue outer;
411
+ return n;
412
+ }
413
+ return -1;
414
+ }
415
+ function f(e, t) {
416
+ let n = t?.includeDelimiter ?? !1, r = u(e);
417
+ if (typeof e == "string") {
418
+ let e = new Uint8Array(), t = new TextDecoder();
419
+ return {
420
+ parse(i, a) {
421
+ let o = new Uint8Array(e.length + i.length);
422
+ o.set(e), o.set(i, e.length), e = o;
423
+ let s;
424
+ for (; (s = d(e, r)) !== -1;) {
425
+ let i = n ? s + r.length : s;
426
+ a(t.decode(e.slice(0, i))), t = new TextDecoder(), e = e.slice(s + r.length);
427
+ }
428
+ },
429
+ reset() {
430
+ e = new Uint8Array(), t = new TextDecoder();
431
+ }
432
+ };
433
+ }
434
+ let i = new Uint8Array();
435
+ return {
436
+ parse(e, t) {
437
+ let a = new Uint8Array(i.length + e.length);
438
+ a.set(i), a.set(e, i.length), i = a;
439
+ let o;
440
+ for (; (o = d(i, r)) !== -1;) {
441
+ let e = n ? o + r.length : o;
442
+ t(i.slice(0, e)), i = i.slice(o + r.length);
443
+ }
444
+ },
445
+ reset() {
446
+ i = new Uint8Array();
447
+ }
448
+ };
449
+ }
450
+ //#endregion
379
451
  //#region src/parsers/FixedLengthParser.ts
380
- function l(e) {
452
+ function p(e) {
381
453
  if (e <= 0) throw Error("FixedLengthParser: length must be greater than 0");
382
454
  let t = new Uint8Array();
383
455
  return {
@@ -391,23 +463,67 @@ function l(e) {
391
463
  };
392
464
  }
393
465
  //#endregion
394
- //#region src/parsers/DelimiterParser.ts
395
- function u(e) {
396
- let t = "", n = new TextDecoder();
466
+ //#region src/parsers/InterByteTimeoutParser.ts
467
+ function m(e) {
468
+ if (e.interval <= 0) throw Error("InterByteTimeoutParser: interval must be greater than 0");
469
+ let t = e.maxBufferSize ?? 65536, n = new Uint8Array(), r = null, i = null;
470
+ function a() {
471
+ r !== null && (clearTimeout(r), r = null), n.length > 0 && i !== null && (i(n.slice()), n = new Uint8Array());
472
+ }
397
473
  return {
398
- parse(r, i) {
399
- t += n.decode(r, { stream: !0 });
400
- let a;
401
- for (; (a = t.indexOf(e)) !== -1;) i(t.slice(0, a)), t = t.slice(a + e.length);
474
+ parse(o, s) {
475
+ i = s, r !== null && (clearTimeout(r), r = null);
476
+ let c = new Uint8Array(n.length + o.length);
477
+ if (c.set(n), c.set(o, n.length), n = c, n.length >= t) {
478
+ a();
479
+ return;
480
+ }
481
+ r = setTimeout(() => {
482
+ r = null, a();
483
+ }, e.interval);
402
484
  },
403
485
  reset() {
404
- t = "", n = new TextDecoder();
486
+ r !== null && (clearTimeout(r), r = null), n = new Uint8Array(), i = null;
487
+ }
488
+ };
489
+ }
490
+ //#endregion
491
+ //#region src/parsers/PacketLengthParser.ts
492
+ function h(e) {
493
+ let t = e?.delimiter ?? 170, n = e?.packetOverhead ?? 2, r = e?.lengthBytes ?? 1, i = e?.lengthOffset ?? 1, a = e?.maxLen ?? 255;
494
+ if (i + r > n) throw Error("PacketLengthParser: lengthOffset + lengthBytes must not exceed packetOverhead");
495
+ let o = new Uint8Array();
496
+ return {
497
+ parse(e, s) {
498
+ let c = new Uint8Array(o.length + e.length);
499
+ for (c.set(o), c.set(e, o.length), o = c;;) {
500
+ let e = o.indexOf(t);
501
+ if (e === -1) {
502
+ o = new Uint8Array();
503
+ break;
504
+ }
505
+ e > 0 && (o = o.slice(e));
506
+ let c = i + r;
507
+ if (o.length < c) break;
508
+ let l = 0;
509
+ for (let e = 0; e < r; e++) l = l << 8 | o[i + e];
510
+ if (l > a) {
511
+ o = o.slice(1);
512
+ continue;
513
+ }
514
+ let u = l + n;
515
+ if (o.length < u) break;
516
+ s(o.slice(0, u)), o = o.slice(u);
517
+ }
518
+ },
519
+ reset() {
520
+ o = new Uint8Array();
405
521
  }
406
522
  };
407
523
  }
408
524
  //#endregion
409
525
  //#region src/parsers/RawParser.ts
410
- function d() {
526
+ function g() {
411
527
  return {
412
528
  parse(e, t) {
413
529
  t(e);
@@ -416,37 +532,207 @@ function d() {
416
532
  };
417
533
  }
418
534
  //#endregion
535
+ //#region src/parsers/ReadlineParser.ts
536
+ function _(e, t) {
537
+ if (t.length === 0) return 0;
538
+ outer: for (let n = 0; n <= e.length - t.length; n++) {
539
+ for (let r = 0; r < t.length; r++) if (e[n + r] !== t[r]) continue outer;
540
+ return n;
541
+ }
542
+ return -1;
543
+ }
544
+ function v(e) {
545
+ let t = e?.encoding ?? "utf-8", n = e?.includeDelimiter ?? !1, r = e?.delimiter ?? "\n", i;
546
+ i = typeof r == "string" ? new TextEncoder().encode(r) : r instanceof Uint8Array ? r : new Uint8Array(r);
547
+ let a = new Uint8Array();
548
+ return {
549
+ parse(e, r) {
550
+ let o = new Uint8Array(a.length + e.length);
551
+ o.set(a), o.set(e, a.length), a = o;
552
+ let s;
553
+ for (; (s = _(a, i)) !== -1;) {
554
+ let e = n ? s + i.length : s;
555
+ r(new TextDecoder(t).decode(a.slice(0, e))), a = a.slice(s + i.length);
556
+ }
557
+ },
558
+ reset() {
559
+ a = new Uint8Array();
560
+ }
561
+ };
562
+ }
563
+ //#endregion
564
+ //#region src/parsers/ReadyParser.ts
565
+ function y(e, t) {
566
+ if (t.length === 0) return 0;
567
+ outer: for (let n = 0; n <= e.length - t.length; n++) {
568
+ for (let r = 0; r < t.length; r++) if (e[n + r] !== t[r]) continue outer;
569
+ return n;
570
+ }
571
+ return -1;
572
+ }
573
+ function b(e) {
574
+ let t = e.delimiter, n;
575
+ n = typeof t == "string" ? new TextEncoder().encode(t) : t instanceof Uint8Array ? t : new Uint8Array(t);
576
+ let r = !1, i = new Uint8Array();
577
+ return {
578
+ parse(t, a) {
579
+ if (r) {
580
+ a(t);
581
+ return;
582
+ }
583
+ let o = new Uint8Array(i.length + t.length);
584
+ o.set(i), o.set(t, i.length), i = o;
585
+ let s = y(i, n);
586
+ if (s === -1) return;
587
+ r = !0, e.onReady?.();
588
+ let c = i.slice(s + n.length);
589
+ i = new Uint8Array(), c.length > 0 && a(c);
590
+ },
591
+ reset() {
592
+ r = !1, i = new Uint8Array();
593
+ }
594
+ };
595
+ }
596
+ //#endregion
597
+ //#region src/parsers/RegexParser.ts
598
+ function x(e) {
599
+ let t = e.regex instanceof RegExp ? e.regex : new RegExp(e.regex), n = e.encoding ?? "utf-8", r = "";
600
+ return {
601
+ parse(e, i) {
602
+ let a = new TextDecoder(n);
603
+ r += a.decode(e);
604
+ let o = r.split(t);
605
+ r = o.pop() ?? "";
606
+ for (let e of o) i(e);
607
+ },
608
+ reset() {
609
+ r = "";
610
+ }
611
+ };
612
+ }
613
+ //#endregion
614
+ //#region src/parsers/SlipParser.ts
615
+ var S = {
616
+ END: 192,
617
+ ESC: 219,
618
+ ESC_END: 220,
619
+ ESC_ESC: 221
620
+ };
621
+ function C(e) {
622
+ let t = e?.END ?? S.END, n = e?.ESC ?? S.ESC, r = e?.ESC_END ?? S.ESC_END, i = e?.ESC_ESC ?? S.ESC_ESC, a = e?.START, o = e?.ESC_START ?? n, s = [], c = !1, l = a === void 0;
623
+ return {
624
+ parse(e, u) {
625
+ for (let d = 0; d < e.length; d++) {
626
+ let f = e[d];
627
+ if (!l) {
628
+ f === a && (l = !0);
629
+ continue;
630
+ }
631
+ if (f === t) {
632
+ s.length > 0 && (u(new Uint8Array(s)), s = []), a !== void 0 && (l = !1), c = !1;
633
+ continue;
634
+ }
635
+ if (c) {
636
+ c = !1, f === r ? s.push(t) : f === i ? s.push(n) : a !== void 0 && f === o ? s.push(a) : s.push(f);
637
+ continue;
638
+ }
639
+ if (f === n) {
640
+ c = !0;
641
+ continue;
642
+ }
643
+ s.push(f);
644
+ }
645
+ },
646
+ reset() {
647
+ s = [], c = !1, l = a === void 0;
648
+ }
649
+ };
650
+ }
651
+ function ee(e, t) {
652
+ let n = t?.END ?? S.END, r = t?.ESC ?? S.ESC, i = t?.ESC_END ?? S.ESC_END, a = t?.ESC_ESC ?? S.ESC_ESC, o = t?.START, s = t?.ESC_START ?? r, c = t?.bluetoothQuirk ?? !1, l = [];
653
+ c && l.push(n);
654
+ for (let t = 0; t < e.length; t++) {
655
+ let c = e[t];
656
+ c === n ? l.push(r, i) : c === r ? l.push(r, a) : o !== void 0 && c === o ? l.push(r, s) : l.push(c);
657
+ }
658
+ return l.push(n), new Uint8Array(l);
659
+ }
660
+ //#endregion
661
+ //#region src/parsers/SpacePacketParser.ts
662
+ function te(e) {
663
+ let t = e?.timeCodeFieldLength ?? 0, n = e?.ancillaryDataFieldLength ?? 0, r = new Uint8Array();
664
+ function i(e) {
665
+ let r = e[0], i = e[1], a = e[2], o = e[3], s = e[4], c = e[5], l = r >> 5 & 7, u = r >> 4 & 1, d = r >> 3 & 1, f = (r & 7) << 8 | i, p = a >> 6 & 3, m = (a & 63) << 8 | o, h = s << 8 | c, g = {
666
+ versionNumber: l,
667
+ identification: {
668
+ apid: f,
669
+ secondaryHeader: d,
670
+ type: u
671
+ },
672
+ sequenceControl: {
673
+ packetName: m,
674
+ sequenceFlags: p
675
+ },
676
+ dataLength: h
677
+ }, _, v = 6;
678
+ if (d === 1) {
679
+ _ = {};
680
+ let r = new TextDecoder("latin1");
681
+ t > 0 && (_.timeCode = r.decode(e.slice(v, v + t)), v += t), n > 0 && (_.ancillaryData = r.decode(e.slice(v, v + n)), v += n);
682
+ }
683
+ let y = new TextDecoder("latin1").decode(e.slice(v));
684
+ return {
685
+ header: g,
686
+ secondaryHeader: _,
687
+ data: y
688
+ };
689
+ }
690
+ return {
691
+ parse(e, t) {
692
+ let n = new Uint8Array(r.length + e.length);
693
+ for (n.set(r), n.set(e, r.length), r = n; r.length >= 6;) {
694
+ let e = 6 + (r[4] << 8 | r[5]) + 1;
695
+ if (r.length < e) break;
696
+ t(i(r.slice(0, e))), r = r.slice(e);
697
+ }
698
+ },
699
+ reset() {
700
+ r = new Uint8Array();
701
+ }
702
+ };
703
+ }
704
+ //#endregion
419
705
  //#region src/adapters/web-usb/WebUsbProvider.ts
420
- var f = 32, p = 34, m = 0, h = 30, g = 3, _ = 7, v = 1, y = 0, b = 771, x = 768, S = 255, C = 8, w = "none", T = 1, E = [
706
+ var w = 32, T = 34, E = 0, D = 30, O = 3, k = 7, A = 1, ne = 0, re = 771, ie = 768, j = 255, M = 8, N = "none", P = 1, F = [
421
707
  16,
422
708
  8,
423
709
  7,
424
710
  6,
425
711
  5
426
- ], D = [1, 2], O = [
712
+ ], I = [1, 2], L = [
427
713
  "none",
428
714
  "even",
429
715
  "odd"
430
- ], k = [
716
+ ], R = [
431
717
  "none",
432
718
  "odd",
433
719
  "even"
434
- ], A = [
720
+ ], z = [
435
721
  1,
436
722
  1.5,
437
723
  2
438
- ], j = {
724
+ ], B = {
439
725
  usbControlInterfaceClass: 2,
440
726
  usbTransferInterfaceClass: 10,
441
727
  protocol: void 0
442
728
  };
443
- function M(e, t) {
729
+ function V(e, t) {
444
730
  let n = e.configurations[0];
445
731
  if (!n) return null;
446
732
  for (let e of n.interfaces) if (e.alternates[0]?.interfaceClass === t) return e;
447
733
  return null;
448
734
  }
449
- function N(e, t) {
735
+ function H(e, t) {
450
736
  let n = e.configurations[0];
451
737
  if (!n) return null;
452
738
  for (let e of n.interfaces) {
@@ -457,17 +743,17 @@ function N(e, t) {
457
743
  }
458
744
  return null;
459
745
  }
460
- function P(e, t) {
746
+ function U(e, t) {
461
747
  let n = e.alternates[0];
462
748
  if (n) {
463
749
  for (let e of n.endpoints) if (e.direction === t) return e;
464
750
  }
465
751
  throw TypeError(`Interface ${e.interfaceNumber} does not have an ${t} endpoint.`);
466
752
  }
467
- function F(e, t) {
753
+ function W(e, t) {
468
754
  return t === 2 ? "cdc_acm" : e.vendorId === 4292 ? "cp210x" : "none";
469
755
  }
470
- var I = class {
756
+ var G = class {
471
757
  device_;
472
758
  endpoint_;
473
759
  onError_;
@@ -492,7 +778,7 @@ var I = class {
492
778
  }
493
779
  })();
494
780
  }
495
- }, L = class {
781
+ }, K = class {
496
782
  device_;
497
783
  endpoint_;
498
784
  onError_;
@@ -507,7 +793,7 @@ var I = class {
507
793
  t.error(String(e)), this.onError_();
508
794
  }
509
795
  }
510
- }, R = class {
796
+ }, q = class {
511
797
  device_;
512
798
  protocol_;
513
799
  controlInterface_;
@@ -525,33 +811,33 @@ var I = class {
525
811
  constructor(e, t) {
526
812
  this.device_ = e;
527
813
  let n = {
528
- ...j,
814
+ ...B,
529
815
  ...t
530
816
  };
531
- this.protocol_ = n.protocol ?? F(e, n.usbControlInterfaceClass);
817
+ this.protocol_ = n.protocol ?? W(e, n.usbControlInterfaceClass);
532
818
  let r = n.usbControlInterfaceClass, i = n.usbTransferInterfaceClass;
533
819
  if (r === i) {
534
- let t = N(e, i);
820
+ let t = H(e, i);
535
821
  if (!t) throw TypeError(`Unable to find interface with class ${i} that has both IN and OUT endpoints.`);
536
822
  this.controlInterface_ = t, this.transferInterface_ = t;
537
823
  } else {
538
- let t = M(e, r);
824
+ let t = V(e, r);
539
825
  if (!t) throw TypeError(`Unable to find control interface with class ${r}.`);
540
- let n = N(e, i) ?? M(e, i);
826
+ let n = H(e, i) ?? V(e, i);
541
827
  if (!n) throw TypeError(`Unable to find transfer interface with class ${i}.`);
542
828
  this.controlInterface_ = t, this.transferInterface_ = n;
543
829
  }
544
- this.inEndpoint_ = P(this.transferInterface_, "in"), this.outEndpoint_ = P(this.transferInterface_, "out");
830
+ this.inEndpoint_ = U(this.transferInterface_, "in"), this.outEndpoint_ = U(this.transferInterface_, "out");
545
831
  }
546
832
  get readable() {
547
- return !this.readable_ && this.device_.opened && (this.readable_ = new ReadableStream(new I(this.device_, this.inEndpoint_, () => {
833
+ return !this.readable_ && this.device_.opened && (this.readable_ = new ReadableStream(new G(this.device_, this.inEndpoint_, () => {
548
834
  this.readable_ = null;
549
- }), { highWaterMark: this.serialOptions_?.bufferSize ?? S })), this.readable_;
835
+ }), { highWaterMark: this.serialOptions_?.bufferSize ?? j })), this.readable_;
550
836
  }
551
837
  get writable() {
552
- return !this.writable_ && this.device_.opened && (this.writable_ = new WritableStream(new L(this.device_, this.outEndpoint_, () => {
838
+ return !this.writable_ && this.device_.opened && (this.writable_ = new WritableStream(new K(this.device_, this.outEndpoint_, () => {
553
839
  this.writable_ = null;
554
- }), new ByteLengthQueuingStrategy({ highWaterMark: this.serialOptions_?.bufferSize ?? S }))), this.writable_;
840
+ }), new ByteLengthQueuingStrategy({ highWaterMark: this.serialOptions_?.bufferSize ?? j }))), this.writable_;
555
841
  }
556
842
  async open(e) {
557
843
  this.serialOptions_ = e, this.validateOptions();
@@ -607,7 +893,7 @@ var I = class {
607
893
  await this.device_.controlTransferOut({
608
894
  requestType: "class",
609
895
  recipient: "interface",
610
- request: p,
896
+ request: T,
611
897
  value: e,
612
898
  index: this.controlInterface_.interfaceNumber
613
899
  });
@@ -615,10 +901,10 @@ var I = class {
615
901
  }
616
902
  async cdcSetLineCoding() {
617
903
  let e = /* @__PURE__ */ new ArrayBuffer(7), t = new DataView(e);
618
- if (t.setUint32(0, this.serialOptions_.baudRate, !0), t.setUint8(4, A.indexOf(this.serialOptions_.stopBits ?? T)), t.setUint8(5, k.indexOf(this.serialOptions_.parity ?? w)), t.setUint8(6, this.serialOptions_.dataBits ?? C), (await this.device_.controlTransferOut({
904
+ if (t.setUint32(0, this.serialOptions_.baudRate, !0), t.setUint8(4, z.indexOf(this.serialOptions_.stopBits ?? P)), t.setUint8(5, R.indexOf(this.serialOptions_.parity ?? N)), t.setUint8(6, this.serialOptions_.dataBits ?? M), (await this.device_.controlTransferOut({
619
905
  requestType: "class",
620
906
  recipient: "interface",
621
- request: f,
907
+ request: w,
622
908
  value: 0,
623
909
  index: this.controlInterface_.interfaceNumber
624
910
  }, e)).status !== "ok") throw new DOMException("Failed to set line coding.", "NetworkError");
@@ -628,37 +914,37 @@ var I = class {
628
914
  await this.device_.controlTransferOut({
629
915
  requestType: "vendor",
630
916
  recipient: "interface",
631
- request: m,
632
- value: v,
917
+ request: E,
918
+ value: A,
633
919
  index: e
634
920
  });
635
921
  let t = /* @__PURE__ */ new ArrayBuffer(4);
636
922
  new DataView(t).setUint32(0, this.serialOptions_.baudRate, !0), await this.device_.controlTransferOut({
637
923
  requestType: "vendor",
638
924
  recipient: "interface",
639
- request: h,
925
+ request: D,
640
926
  value: 0,
641
927
  index: e
642
928
  }, t);
643
- let n = this.serialOptions_.dataBits ?? C, r = {
929
+ let n = this.serialOptions_.dataBits ?? M, r = {
644
930
  none: 0,
645
931
  odd: 16,
646
932
  even: 32
647
- }[this.serialOptions_.parity ?? w] ?? 0, i = ({
933
+ }[this.serialOptions_.parity ?? N] ?? 0, i = ({
648
934
  1: 0,
649
935
  2: 2
650
- }[this.serialOptions_.stopBits ?? T] ?? 0) << 8 | r | n;
936
+ }[this.serialOptions_.stopBits ?? P] ?? 0) << 8 | r | n;
651
937
  await this.device_.controlTransferOut({
652
938
  requestType: "vendor",
653
939
  recipient: "interface",
654
- request: g,
940
+ request: O,
655
941
  value: i,
656
942
  index: e
657
943
  }), await this.device_.controlTransferOut({
658
944
  requestType: "vendor",
659
945
  recipient: "interface",
660
- request: _,
661
- value: b,
946
+ request: k,
947
+ value: re,
662
948
  index: e
663
949
  });
664
950
  }
@@ -667,28 +953,28 @@ var I = class {
667
953
  await this.device_.controlTransferOut({
668
954
  requestType: "vendor",
669
955
  recipient: "interface",
670
- request: _,
671
- value: x,
956
+ request: k,
957
+ value: ie,
672
958
  index: e
673
959
  }), await this.device_.controlTransferOut({
674
960
  requestType: "vendor",
675
961
  recipient: "interface",
676
- request: m,
677
- value: y,
962
+ request: E,
963
+ value: ne,
678
964
  index: e
679
965
  });
680
966
  }
681
967
  validateOptions() {
682
968
  if (this.serialOptions_.baudRate % 1 != 0) throw RangeError(`Invalid baud rate: ${this.serialOptions_.baudRate}`);
683
- if (this.serialOptions_.dataBits !== void 0 && !E.includes(this.serialOptions_.dataBits)) throw RangeError(`Invalid dataBits: ${this.serialOptions_.dataBits}`);
684
- if (this.serialOptions_.stopBits !== void 0 && !D.includes(this.serialOptions_.stopBits)) throw RangeError(`Invalid stopBits: ${this.serialOptions_.stopBits}`);
685
- if (this.serialOptions_.parity !== void 0 && !O.includes(this.serialOptions_.parity)) throw RangeError(`Invalid parity: ${this.serialOptions_.parity}`);
969
+ if (this.serialOptions_.dataBits !== void 0 && !F.includes(this.serialOptions_.dataBits)) throw RangeError(`Invalid dataBits: ${this.serialOptions_.dataBits}`);
970
+ if (this.serialOptions_.stopBits !== void 0 && !I.includes(this.serialOptions_.stopBits)) throw RangeError(`Invalid stopBits: ${this.serialOptions_.stopBits}`);
971
+ if (this.serialOptions_.parity !== void 0 && !L.includes(this.serialOptions_.parity)) throw RangeError(`Invalid parity: ${this.serialOptions_.parity}`);
686
972
  }
687
- }, z = class {
973
+ }, J = class {
688
974
  options_;
689
975
  constructor(e) {
690
976
  this.options_ = {
691
- ...j,
977
+ ...B,
692
978
  ...e
693
979
  };
694
980
  }
@@ -702,7 +988,7 @@ var I = class {
702
988
  t.usbVendorId !== void 0 && (e.vendorId = t.usbVendorId), t.usbProductId !== void 0 && (e.productId = t.usbProductId), n.usbControlInterfaceClass !== void 0 && n.usbControlInterfaceClass !== 255 ? e.classCode = n.usbControlInterfaceClass : e.vendorId === void 0 && e.productId === void 0 && (e.classCode = n.usbControlInterfaceClass ?? 2), r.push(e);
703
989
  }
704
990
  else r.push({ classCode: n.usbControlInterfaceClass ?? 2 });
705
- return new R(await navigator.usb.requestDevice({ filters: r }), n);
991
+ return new q(await navigator.usb.requestDevice({ filters: r }), n);
706
992
  }
707
993
  async getPorts(e) {
708
994
  let t = {
@@ -710,13 +996,13 @@ var I = class {
710
996
  ...e
711
997
  }, n = await navigator.usb.getDevices(), r = [];
712
998
  for (let e of n) try {
713
- let n = new R(e, t);
999
+ let n = new q(e, t);
714
1000
  r.push(n);
715
1001
  } catch {}
716
1002
  return r;
717
1003
  }
718
- }, B = "6e400001-b5a3-f393-e0a9-e50e24dcca9e", V = "6e400003-b5a3-f393-e0a9-e50e24dcca9e", H = "6e400002-b5a3-f393-e0a9-e50e24dcca9e", U = 20, W = 10;
719
- function G(e) {
1004
+ }, Y = "6e400001-b5a3-f393-e0a9-e50e24dcca9e", ae = "6e400003-b5a3-f393-e0a9-e50e24dcca9e", oe = "6e400002-b5a3-f393-e0a9-e50e24dcca9e", X = 20, se = 10;
1005
+ function ce(e) {
720
1006
  let t = null, n = null, r = null;
721
1007
  return {
722
1008
  get readable() {
@@ -731,16 +1017,16 @@ function G(e) {
731
1017
  async open() {
732
1018
  if (!e.gatt) throw Error("GATT not available on this Bluetooth device.");
733
1019
  r = await e.gatt.connect();
734
- let i = await r.getPrimaryService(B), a = await i.getCharacteristic(V), o = await i.getCharacteristic(H);
1020
+ let i = await r.getPrimaryService(Y), a = await i.getCharacteristic(ae), o = await i.getCharacteristic(oe);
735
1021
  await a.startNotifications(), t = new ReadableStream({ start(e) {
736
1022
  a.addEventListener("characteristicvaluechanged", (t) => {
737
1023
  let n = t.target.value.buffer;
738
1024
  e.enqueue(new Uint8Array(n));
739
1025
  });
740
1026
  } }), n = new WritableStream({ async write(e) {
741
- for (let t = 0; t < e.length; t += U) {
742
- let n = e.slice(t, t + U);
743
- await o.writeValueWithoutResponse(n), t + U < e.length && await new Promise((e) => setTimeout(e, W));
1027
+ for (let t = 0; t < e.length; t += X) {
1028
+ let n = e.slice(t, t + X);
1029
+ await o.writeValueWithoutResponse(n), t + X < e.length && await new Promise((e) => setTimeout(e, se));
744
1030
  }
745
1031
  } });
746
1032
  },
@@ -749,11 +1035,11 @@ function G(e) {
749
1035
  }
750
1036
  };
751
1037
  }
752
- function K() {
1038
+ function le() {
753
1039
  return {
754
1040
  async requestPort() {
755
1041
  if (!navigator.bluetooth) throw Error("Web Bluetooth API is not supported in this browser. Use Chrome on Android, macOS, or ChromeOS.");
756
- return G(await navigator.bluetooth.requestDevice({ filters: [{ services: [B] }] }));
1042
+ return ce(await navigator.bluetooth.requestDevice({ filters: [{ services: [Y] }] }));
757
1043
  },
758
1044
  async getPorts() {
759
1045
  return [];
@@ -762,12 +1048,12 @@ function K() {
762
1048
  }
763
1049
  //#endregion
764
1050
  //#region src/adapters/websocket/WebSocketProvider.ts
765
- function q(e) {
1051
+ function Z(e) {
766
1052
  return new Promise((t, n) => {
767
1053
  e.addEventListener("open", () => t(), { once: !0 }), e.addEventListener("error", (e) => n(e), { once: !0 });
768
1054
  });
769
1055
  }
770
- function J(e, t) {
1056
+ function Q(e, t) {
771
1057
  return new Promise((n) => {
772
1058
  let r = (i) => {
773
1059
  let a = JSON.parse(i.data);
@@ -776,7 +1062,7 @@ function J(e, t) {
776
1062
  e.addEventListener("message", r);
777
1063
  });
778
1064
  }
779
- function Y(e, t) {
1065
+ function $(e, t) {
780
1066
  let n = null, r = null;
781
1067
  return {
782
1068
  get readable() {
@@ -803,7 +1089,7 @@ function Y(e, t) {
803
1089
  type: "delimiter",
804
1090
  value: "\\n"
805
1091
  }
806
- })), await J(e, "opened");
1092
+ })), await Q(e, "opened");
807
1093
  let a = [], o = null, s = !1;
808
1094
  function c(e) {
809
1095
  let t = JSON.parse(e.data);
@@ -834,26 +1120,26 @@ function Y(e, t) {
834
1120
  }
835
1121
  };
836
1122
  }
837
- function X(e) {
1123
+ function ue(e) {
838
1124
  return {
839
1125
  async requestPort(t) {
840
1126
  let n = new WebSocket(e);
841
- await q(n), n.send(JSON.stringify({
1127
+ await Z(n), n.send(JSON.stringify({
842
1128
  type: "list-ports",
843
1129
  filters: t?.filters ?? []
844
1130
  }));
845
- let r = (await J(n, "port-list"))[0];
1131
+ let r = (await Q(n, "port-list"))[0];
846
1132
  if (!r) throw Error("No ports available on the bridge server. Make sure the Node.js server is running and a device is connected.");
847
- return Y(n, r);
1133
+ return $(n, r);
848
1134
  },
849
1135
  async getPorts() {
850
1136
  let t = new WebSocket(e);
851
- return await q(t), t.send(JSON.stringify({
1137
+ return await Z(t), t.send(JSON.stringify({
852
1138
  type: "list-ports",
853
1139
  filters: []
854
- })), (await J(t, "port-list")).map((e) => Y(t, e));
1140
+ })), (await Q(t, "port-list")).map((e) => $(t, e));
855
1141
  }
856
1142
  };
857
1143
  }
858
1144
  //#endregion
859
- export { c as AbstractSerialDevice, n as CommandQueue, e as SerialEventEmitter, i as SerialPermissionError, r as SerialPortConflictError, o as SerialReadError, t as SerialRegistry, a as SerialTimeoutError, s as SerialWriteError, z as WebUsbProvider, K as createBluetoothProvider, X as createWebSocketProvider, u as delimiter, l as fixedLength, d as raw };
1145
+ export { c as AbstractSerialDevice, n as CommandQueue, e as SerialEventEmitter, i as SerialPermissionError, r as SerialPortConflictError, o as SerialReadError, t as SerialRegistry, a as SerialTimeoutError, s as SerialWriteError, J as WebUsbProvider, l as ccTalk, le as createBluetoothProvider, ue as createWebSocketProvider, f as delimiter, p as fixedLength, m as interByteTimeout, h as packetLength, g as raw, v as readline, b as readyParser, x as regexParser, C as slipDecoder, ee as slipEncode, te as spacePacket };
@@ -1 +1,2 @@
1
- (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.WebSerialCore={}))})(this,function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var t=class{listeners={};on(e,t){return this.listeners[e]||(this.listeners[e]=new Set),this.listeners[e].add(t),this}off(e,t){return this.listeners[e]&&this.listeners[e].delete(t),this}emit(e,...t){let n=this.listeners[e];if(!n||n.size===0)return!1;for(let e of n)e(...t);return!0}},n=class{static instances=new Set;static portInstanceMap=new WeakMap;static getInstances(){return Array.from(this.instances)}static register(e){this.instances.add(e)}static unregister(e){this.instances.delete(e)}static isPortInUse(e,t){let n=this.portInstanceMap.get(e);return n!==void 0&&n!==t}static lockPort(e,t){this.portInstanceMap.set(e,t)}static unlockPort(e){this.portInstanceMap.delete(e)}},r=class{queue=[];isProcessing=!1;isPaused=!0;timeoutId=null;commandTimeout;onSend;onTimeout;constructor(e){this.commandTimeout=e.commandTimeout,this.onSend=e.onSend,this.onTimeout=e.onTimeout}get queueSize(){return this.queue.length}enqueue(e){this.queue.push(e),this.tryProcessNext()}advance(){this.clearCommandTimeout(),this.isProcessing=!1,this.tryProcessNext()}pause(){this.isPaused=!0,this.clearCommandTimeout(),this.isProcessing=!1}resume(){this.isPaused=!1,this.tryProcessNext()}clear(){this.queue=[],this.clearCommandTimeout(),this.isProcessing=!1}snapshot(){return[...this.queue]}restore(e){this.queue=[...e,...this.queue]}tryProcessNext(){if(this.isPaused||this.isProcessing||this.queue.length===0)return;this.isProcessing=!0;let e=this.queue.shift();this.commandTimeout>0&&(this.timeoutId=setTimeout(()=>{this.timeoutId=null,this.onTimeout(e),this.advance()},this.commandTimeout)),this.onSend(e).catch(()=>{this.advance()})}clearCommandTimeout(){this.timeoutId!==null&&(clearTimeout(this.timeoutId),this.timeoutId=null)}},i=class e extends Error{constructor(t){super(t),this.name=`SerialPortConflictError`,Object.setPrototypeOf(this,e.prototype)}},a=class e extends Error{constructor(t){super(t),this.name=`SerialPermissionError`,Object.setPrototypeOf(this,e.prototype)}},o=class e extends Error{constructor(t){super(t),this.name=`SerialTimeoutError`,Object.setPrototypeOf(this,e.prototype)}},s=class e extends Error{constructor(t){super(t),this.name=`SerialReadError`,Object.setPrototypeOf(this,e.prototype)}},c=class e extends Error{constructor(t){super(t),this.name=`SerialWriteError`,Object.setPrototypeOf(this,e.prototype)}},l=class e extends t{port=null;reader=null;writer=null;queue;options;isConnecting=!1;abortController=null;userInitiatedDisconnect=!1;reconnectTimerId=null;isHandshaking=!1;static customProvider=null;static polyfillOptions;constructor(e){super(),this.options={baudRate:e.baudRate,dataBits:e.dataBits??8,stopBits:e.stopBits??1,parity:e.parity??`none`,bufferSize:e.bufferSize??255,flowControl:e.flowControl??`none`,filters:e.filters??[],commandTimeout:e.commandTimeout??0,parser:e.parser,autoReconnect:e.autoReconnect??!1,autoReconnectInterval:e.autoReconnectInterval??1500,handshakeTimeout:e.handshakeTimeout??2e3,provider:e.provider,polyfillOptions:e.polyfillOptions},this.queue=new r({commandTimeout:this.options.commandTimeout,onSend:async e=>{await this.writeToPort(e),this.emit(`serial:sent`,e,this)},onTimeout:e=>{this.emit(`serial:timeout`,e,this)}}),this.on(`serial:data`,()=>{this.queue.advance()}),n.register(this)}async handshake(){return!0}async connect(){if(!this.isConnecting&&!this.port){this.isConnecting=!0,this.emit(`serial:connecting`,this);try{let t=this.getSerial();if(!t)throw Error(`Web Serial API is not supported in this browser. Use AbstractSerialDevice.setProvider() to set a WebUSB polyfill.`);if(this.port=await this.findAndValidatePort(),!this.port){let n;try{n=await t.requestPort({filters:this.options.filters},this.options.polyfillOptions??e.polyfillOptions)}catch(e){throw e instanceof DOMException&&(e.name===`NotFoundError`||e.name===`SecurityError`||e.name===`AbortError`)?new a(e instanceof Error?e.message:String(e)):e instanceof Error?e:Error(String(e))}if(!await this.openAndHandshake(n))throw Error(`Handshake failed: the selected device did not respond correctly.`);this.port=n}this.abortController=new AbortController,this.queue.resume(),this.emit(`serial:connected`,this)}catch(e){if(e instanceof a?this.emit(`serial:need-permission`,this):this.emit(`serial:error`,e instanceof Error?e:Error(String(e)),this),this.port){n.unlockPort(this.port);try{await this.port.close()}catch{}this.port=null}throw e}finally{this.isConnecting=!1}}}async disconnect(){this.port&&(this.userInitiatedDisconnect=!0,this.stopReconnecting(),await this.cleanupPort())}isConnected(){return!!(this.port&&this.port.connected&&this.port.readable&&this.port.writable)}isDisconnected(){return!this.isConnected()}async cleanupPort(){if(this.port){this.queue.pause(),this.abortController?.abort(),this.abortController=null;try{let e=this.reader,t=this.writer;if(this.reader=null,this.writer=null,e){try{await e.cancel()}catch{}try{e.releaseLock()}catch{}}if(t){try{await t.close()}catch{}try{t.releaseLock()}catch{}}try{await this.port.close()}catch{}}catch(e){this.emit(`serial:error`,e instanceof Error?e:Error(String(e)),this)}finally{this.port&&n.unlockPort(this.port),this.port=null,this.options.parser?.reset?.(),this.emit(`serial:disconnected`,this),!this.userInitiatedDisconnect&&this.options.autoReconnect&&this.startReconnecting(),this.userInitiatedDisconnect=!1}}}async forget(){await this.disconnect(),this.port&&typeof this.port.forget==`function`&&await this.port.forget(),n.unregister(this)}async send(e){let t;t=typeof e==`string`?new TextEncoder().encode(e):e,t.length>0&&this.queue.enqueue(t)}clearQueue(){this.queue.clear(),this.emit(`serial:queue-empty`,this)}async writeToPort(e){if(!this.port||!this.port.writable)throw new c(`Port not writable.`);this.writer=this.port.writable.getWriter();try{await this.writer.write(e)}catch(e){throw new c(e instanceof Error?e.message:String(e))}finally{this.writer.releaseLock(),this.writer=null}}async readLoop(){if(!(!this.port||!this.port.readable)&&!this.reader){this.reader=this.port.readable.getReader();try{for(;;){let{value:e,done:t}=await this.reader.read();if(t)break;e&&(this.options.parser?this.options.parser.parse(e,e=>{this.emit(`serial:data`,e,this)}):this.emit(`serial:data`,e,this))}}catch(e){if(this.port)throw new s(e instanceof Error?e.message:String(e))}finally{if(this.reader){try{this.reader.releaseLock()}catch{}this.reader=null}}}}async openAndHandshake(e){let t=this;if(n.isPortInUse(e,t))return!1;n.lockPort(e,t);try{await e.open({baudRate:this.options.baudRate,dataBits:this.options.dataBits,stopBits:this.options.stopBits,parity:this.options.parity,bufferSize:this.options.bufferSize,flowControl:this.options.flowControl})}catch(t){throw n.unlockPort(e),t instanceof Error?t:Error(String(t))}this.port=e,this.abortController=new AbortController;let r=this.queue.snapshot();this.isHandshaking=!0,this.readLoop().catch(e=>{!this.isHandshaking&&this.port&&(this.emit(`serial:error`,e,this),this.cleanupPort())}),this.queue.resume();try{let t=await this.runHandshakeWithTimeout();return this.isHandshaking=!1,t?(this.queue.pause(),this.queue.clear(),this.queue.restore(r),this.options.parser?.reset?.(),!0):(await this.teardownHandshake(e,r),!1)}catch{return this.isHandshaking=!1,await this.teardownHandshake(e,r),!1}}async teardownHandshake(e,t){this.queue.pause(),this.queue.clear(),this.queue.restore(t),await this.stopReader(),this.port=null,this.abortController=null,this.options.parser?.reset?.();try{await e.close()}catch{}n.unlockPort(e)}async stopReader(){let e=this.reader;if(this.reader=null,e){try{await e.cancel()}catch{}try{e.releaseLock()}catch{}}}async runHandshakeWithTimeout(){let e=this.options.handshakeTimeout??2e3;return Promise.race([this.handshake(),new Promise(t=>setTimeout(()=>t(!1),e))])}async findAndValidatePort(){let t=this.getSerial();if(!t)return null;let r=await t.getPorts(this.options.polyfillOptions??e.polyfillOptions);if(r.length===0)return null;let i=this.options.filters??[],a=this;for(let e of r)if(!n.isPortInUse(e,a)){if(i.length>0){let t=e.getInfo();if(!i.some(e=>{let n=e.usbVendorId===void 0||e.usbVendorId===t.usbVendorId,r=e.usbProductId===void 0||e.usbProductId===t.usbProductId;return n&&r}))continue}try{if(await this.openAndHandshake(e))return e}catch{}}return null}startReconnecting(){this.reconnectTimerId||=(this.emit(`serial:reconnecting`,this),setInterval(async()=>{if(this.port||this.isConnecting){this.stopReconnecting();return}try{let e=await this.findAndValidatePort();e&&(this.stopReconnecting(),await this.reconnect(e))}catch{}},this.options.autoReconnectInterval))}stopReconnecting(){this.reconnectTimerId&&=(clearInterval(this.reconnectTimerId),null)}async reconnect(e){if(!(this.isConnecting||this.port)){this.isConnecting=!0,this.emit(`serial:connecting`,this);try{this.port=e,this.abortController=new AbortController,this.queue.resume(),this.emit(`serial:connected`,this)}catch(e){this.emit(`serial:error`,e instanceof Error?e:Error(String(e)),this),this.port&&=(n.unlockPort(this.port),null),this.options.autoReconnect&&this.startReconnecting()}finally{this.isConnecting=!1}}}static getInstances(){return n.getInstances()}static async connectAll(){let e=n.getInstances();for(let t of e)try{await t.connect()}catch{}}static setProvider(t,n){e.customProvider=t,e.polyfillOptions=n}getSerial(){return this.options.provider?this.options.provider:e.customProvider?e.customProvider:typeof navigator<`u`&&navigator.serial?navigator.serial:null}};function u(e){if(e<=0)throw Error(`FixedLengthParser: length must be greater than 0`);let t=new Uint8Array;return{parse(n,r){let i=new Uint8Array(t.length+n.length);for(i.set(t),i.set(n,t.length),t=i;t.length>=e;)r(t.slice(0,e)),t=t.slice(e)},reset(){t=new Uint8Array}}}function d(e){let t=``,n=new TextDecoder;return{parse(r,i){t+=n.decode(r,{stream:!0});let a;for(;(a=t.indexOf(e))!==-1;)i(t.slice(0,a)),t=t.slice(a+e.length)},reset(){t=``,n=new TextDecoder}}}function f(){return{parse(e,t){t(e)},reset(){}}}var p=32,m=34,h=0,g=30,_=3,v=7,y=1,b=0,x=771,S=768,C=255,w=8,T=`none`,E=1,D=[16,8,7,6,5],O=[1,2],k=[`none`,`even`,`odd`],A=[`none`,`odd`,`even`],j=[1,1.5,2],M={usbControlInterfaceClass:2,usbTransferInterfaceClass:10,protocol:void 0};function N(e,t){let n=e.configurations[0];if(!n)return null;for(let e of n.interfaces)if(e.alternates[0]?.interfaceClass===t)return e;return null}function P(e,t){let n=e.configurations[0];if(!n)return null;for(let e of n.interfaces){let n=e.alternates[0];if(!n||n.interfaceClass!==t)continue;let r=n.endpoints.some(e=>e.direction===`in`),i=n.endpoints.some(e=>e.direction===`out`);if(r&&i)return e}return null}function F(e,t){let n=e.alternates[0];if(n){for(let e of n.endpoints)if(e.direction===t)return e}throw TypeError(`Interface ${e.interfaceNumber} does not have an ${t} endpoint.`)}function I(e,t){return t===2?`cdc_acm`:e.vendorId===4292?`cp210x`:`none`}var L=class{device_;endpoint_;onError_;constructor(e,t,n){this.device_=e,this.endpoint_=t,this.onError_=n}pull(e){(async()=>{let t=this.endpoint_.packetSize;try{let n=await this.device_.transferIn(this.endpoint_.endpointNumber,t);if(n.status!==`ok`){e.error(`USB error: ${n.status}`),this.onError_();return}if(n.data?.buffer&&n.data.byteLength>0){let t=new Uint8Array(n.data.buffer,n.data.byteOffset,n.data.byteLength);t.length>0&&e.enqueue(t)}}catch(t){e.error(String(t)),this.onError_()}})()}},R=class{device_;endpoint_;onError_;constructor(e,t,n){this.device_=e,this.endpoint_=t,this.onError_=n}async write(e,t){try{let n=await this.device_.transferOut(this.endpoint_.endpointNumber,e.buffer);n.status!==`ok`&&(t.error(n.status),this.onError_())}catch(e){t.error(String(e)),this.onError_()}}},z=class{device_;protocol_;controlInterface_;transferInterface_;inEndpoint_;outEndpoint_;serialOptions_;readable_=null;writable_=null;cdcOutputSignals_={dataTerminalReady:!1,requestToSend:!1,break:!1};constructor(e,t){this.device_=e;let n={...M,...t};this.protocol_=n.protocol??I(e,n.usbControlInterfaceClass);let r=n.usbControlInterfaceClass,i=n.usbTransferInterfaceClass;if(r===i){let t=P(e,i);if(!t)throw TypeError(`Unable to find interface with class ${i} that has both IN and OUT endpoints.`);this.controlInterface_=t,this.transferInterface_=t}else{let t=N(e,r);if(!t)throw TypeError(`Unable to find control interface with class ${r}.`);let n=P(e,i)??N(e,i);if(!n)throw TypeError(`Unable to find transfer interface with class ${i}.`);this.controlInterface_=t,this.transferInterface_=n}this.inEndpoint_=F(this.transferInterface_,`in`),this.outEndpoint_=F(this.transferInterface_,`out`)}get readable(){return!this.readable_&&this.device_.opened&&(this.readable_=new ReadableStream(new L(this.device_,this.inEndpoint_,()=>{this.readable_=null}),{highWaterMark:this.serialOptions_?.bufferSize??C})),this.readable_}get writable(){return!this.writable_&&this.device_.opened&&(this.writable_=new WritableStream(new R(this.device_,this.outEndpoint_,()=>{this.writable_=null}),new ByteLengthQueuingStrategy({highWaterMark:this.serialOptions_?.bufferSize??C}))),this.writable_}async open(e){this.serialOptions_=e,this.validateOptions();try{switch(await this.device_.open(),this.device_.configuration===null&&await this.device_.selectConfiguration(1),await this.device_.claimInterface(this.controlInterface_.interfaceNumber),this.controlInterface_!==this.transferInterface_&&await this.device_.claimInterface(this.transferInterface_.interfaceNumber),this.protocol_){case`cdc_acm`:await this.cdcInit();break;case`cp210x`:await this.cp210xInit();break;case`none`:break}}catch(e){throw this.device_.opened&&await this.device_.close(),Error(`Error setting up device: `+(e instanceof Error?e.message:String(e)),{cause:e})}}async close(){let e=[];if(this.readable_&&e.push(this.readable_.cancel()),this.writable_&&e.push(this.writable_.abort()),await Promise.all(e),this.readable_=null,this.writable_=null,this.device_.opened){switch(this.protocol_){case`cdc_acm`:await this.cdcSetSignals({dataTerminalReady:!1,requestToSend:!1});break;case`cp210x`:await this.cp210xDeinit();break}await this.device_.close()}}async forget(){return this.device_.forget()}getInfo(){return{usbVendorId:this.device_.vendorId,usbProductId:this.device_.productId}}async cdcInit(){await this.cdcSetLineCoding(),await this.cdcSetSignals({dataTerminalReady:!0})}async cdcSetSignals(e){if(this.cdcOutputSignals_={...this.cdcOutputSignals_,...e},e.dataTerminalReady!==void 0||e.requestToSend!==void 0){let e=!!this.cdcOutputSignals_.dataTerminalReady|(this.cdcOutputSignals_.requestToSend?2:0);await this.device_.controlTransferOut({requestType:`class`,recipient:`interface`,request:m,value:e,index:this.controlInterface_.interfaceNumber})}}async cdcSetLineCoding(){let e=new ArrayBuffer(7),t=new DataView(e);if(t.setUint32(0,this.serialOptions_.baudRate,!0),t.setUint8(4,j.indexOf(this.serialOptions_.stopBits??E)),t.setUint8(5,A.indexOf(this.serialOptions_.parity??T)),t.setUint8(6,this.serialOptions_.dataBits??w),(await this.device_.controlTransferOut({requestType:`class`,recipient:`interface`,request:p,value:0,index:this.controlInterface_.interfaceNumber},e)).status!==`ok`)throw new DOMException(`Failed to set line coding.`,`NetworkError`)}async cp210xInit(){let e=this.controlInterface_.interfaceNumber;await this.device_.controlTransferOut({requestType:`vendor`,recipient:`interface`,request:h,value:y,index:e});let t=new ArrayBuffer(4);new DataView(t).setUint32(0,this.serialOptions_.baudRate,!0),await this.device_.controlTransferOut({requestType:`vendor`,recipient:`interface`,request:g,value:0,index:e},t);let n=this.serialOptions_.dataBits??w,r={none:0,odd:16,even:32}[this.serialOptions_.parity??T]??0,i=({1:0,2:2}[this.serialOptions_.stopBits??E]??0)<<8|r|n;await this.device_.controlTransferOut({requestType:`vendor`,recipient:`interface`,request:_,value:i,index:e}),await this.device_.controlTransferOut({requestType:`vendor`,recipient:`interface`,request:v,value:x,index:e})}async cp210xDeinit(){let e=this.controlInterface_.interfaceNumber;await this.device_.controlTransferOut({requestType:`vendor`,recipient:`interface`,request:v,value:S,index:e}),await this.device_.controlTransferOut({requestType:`vendor`,recipient:`interface`,request:h,value:b,index:e})}validateOptions(){if(this.serialOptions_.baudRate%1!=0)throw RangeError(`Invalid baud rate: ${this.serialOptions_.baudRate}`);if(this.serialOptions_.dataBits!==void 0&&!D.includes(this.serialOptions_.dataBits))throw RangeError(`Invalid dataBits: ${this.serialOptions_.dataBits}`);if(this.serialOptions_.stopBits!==void 0&&!O.includes(this.serialOptions_.stopBits))throw RangeError(`Invalid stopBits: ${this.serialOptions_.stopBits}`);if(this.serialOptions_.parity!==void 0&&!k.includes(this.serialOptions_.parity))throw RangeError(`Invalid parity: ${this.serialOptions_.parity}`)}},B=class{options_;constructor(e){this.options_={...M,...e}}async requestPort(e,t){let n={...this.options_,...t},r=[];if(e?.filters&&e.filters.length>0)for(let t of e.filters){let e={};t.usbVendorId!==void 0&&(e.vendorId=t.usbVendorId),t.usbProductId!==void 0&&(e.productId=t.usbProductId),n.usbControlInterfaceClass!==void 0&&n.usbControlInterfaceClass!==255?e.classCode=n.usbControlInterfaceClass:e.vendorId===void 0&&e.productId===void 0&&(e.classCode=n.usbControlInterfaceClass??2),r.push(e)}else r.push({classCode:n.usbControlInterfaceClass??2});return new z(await navigator.usb.requestDevice({filters:r}),n)}async getPorts(e){let t={...this.options_,...e},n=await navigator.usb.getDevices(),r=[];for(let e of n)try{let n=new z(e,t);r.push(n)}catch{}return r}},V=`6e400001-b5a3-f393-e0a9-e50e24dcca9e`,H=`6e400003-b5a3-f393-e0a9-e50e24dcca9e`,U=`6e400002-b5a3-f393-e0a9-e50e24dcca9e`,W=20,G=10;function K(e){let t=null,n=null,r=null;return{get readable(){return t},get writable(){return n},getInfo(){return{}},async open(){if(!e.gatt)throw Error(`GATT not available on this Bluetooth device.`);r=await e.gatt.connect();let i=await r.getPrimaryService(V),a=await i.getCharacteristic(H),o=await i.getCharacteristic(U);await a.startNotifications(),t=new ReadableStream({start(e){a.addEventListener(`characteristicvaluechanged`,t=>{let n=t.target.value.buffer;e.enqueue(new Uint8Array(n))})}}),n=new WritableStream({async write(e){for(let t=0;t<e.length;t+=W){let n=e.slice(t,t+W);await o.writeValueWithoutResponse(n),t+W<e.length&&await new Promise(e=>setTimeout(e,G))}}})},async close(){r?.connected&&r.disconnect(),t=null,n=null}}}function q(){return{async requestPort(){if(!navigator.bluetooth)throw Error(`Web Bluetooth API is not supported in this browser. Use Chrome on Android, macOS, or ChromeOS.`);return K(await navigator.bluetooth.requestDevice({filters:[{services:[V]}]}))},async getPorts(){return[]}}}function J(e){return new Promise((t,n)=>{e.addEventListener(`open`,()=>t(),{once:!0}),e.addEventListener(`error`,e=>n(e),{once:!0})})}function Y(e,t){return new Promise(n=>{let r=i=>{let a=JSON.parse(i.data);a.type===t&&(e.removeEventListener(`message`,r),n(a.payload))};e.addEventListener(`message`,r)})}function X(e,t){let n=null,r=null;return{get readable(){return n},get writable(){return r},getInfo(){return{usbVendorId:t.vendorId,usbProductId:t.productId}},async open(i){e.send(JSON.stringify({type:`open`,path:t.path,baudRate:i.baudRate,dataBits:i.dataBits,stopBits:i.stopBits,parity:i.parity,parser:{type:`delimiter`,value:`\\n`}})),await Y(e,`opened`);let a=[],o=null,s=!1;function c(e){let t=JSON.parse(e.data);if(t.type===`data`&&t.bytes){let e=new Uint8Array(t.bytes);o?o.enqueue(e):a.push(e)}t.type===`closed`&&(s=!0,o&&o.close())}e.addEventListener(`message`,c),n=new ReadableStream({start(e){o=e;for(let t of a)e.enqueue(t);a.length=0,s&&e.close()},cancel(){e.removeEventListener(`message`,c),o=null}}),r=new WritableStream({write(t){e.send(JSON.stringify({type:`write`,bytes:Array.from(t)}))}})},async close(){e.send(JSON.stringify({type:`close`})),n=null,r=null,e.close()}}}function Z(e){return{async requestPort(t){let n=new WebSocket(e);await J(n),n.send(JSON.stringify({type:`list-ports`,filters:t?.filters??[]}));let r=(await Y(n,`port-list`))[0];if(!r)throw Error(`No ports available on the bridge server. Make sure the Node.js server is running and a device is connected.`);return X(n,r)},async getPorts(){let t=new WebSocket(e);return await J(t),t.send(JSON.stringify({type:`list-ports`,filters:[]})),(await Y(t,`port-list`)).map(e=>X(t,e))}}}e.AbstractSerialDevice=l,e.CommandQueue=r,e.SerialEventEmitter=t,e.SerialPermissionError=a,e.SerialPortConflictError=i,e.SerialReadError=s,e.SerialRegistry=n,e.SerialTimeoutError=o,e.SerialWriteError=c,e.WebUsbProvider=B,e.createBluetoothProvider=q,e.createWebSocketProvider=Z,e.delimiter=d,e.fixedLength=u,e.raw=f});
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.WebSerialCore={}))})(this,function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var t=class{listeners={};on(e,t){return this.listeners[e]||(this.listeners[e]=new Set),this.listeners[e].add(t),this}off(e,t){return this.listeners[e]&&this.listeners[e].delete(t),this}emit(e,...t){let n=this.listeners[e];if(!n||n.size===0)return!1;for(let e of n)e(...t);return!0}},n=class{static instances=new Set;static portInstanceMap=new WeakMap;static getInstances(){return Array.from(this.instances)}static register(e){this.instances.add(e)}static unregister(e){this.instances.delete(e)}static isPortInUse(e,t){let n=this.portInstanceMap.get(e);return n!==void 0&&n!==t}static lockPort(e,t){this.portInstanceMap.set(e,t)}static unlockPort(e){this.portInstanceMap.delete(e)}},r=class{queue=[];isProcessing=!1;isPaused=!0;timeoutId=null;commandTimeout;onSend;onTimeout;constructor(e){this.commandTimeout=e.commandTimeout,this.onSend=e.onSend,this.onTimeout=e.onTimeout}get queueSize(){return this.queue.length}enqueue(e){this.queue.push(e),this.tryProcessNext()}advance(){this.clearCommandTimeout(),this.isProcessing=!1,this.tryProcessNext()}pause(){this.isPaused=!0,this.clearCommandTimeout(),this.isProcessing=!1}resume(){this.isPaused=!1,this.tryProcessNext()}clear(){this.queue=[],this.clearCommandTimeout(),this.isProcessing=!1}snapshot(){return[...this.queue]}restore(e){this.queue=[...e,...this.queue]}tryProcessNext(){if(this.isPaused||this.isProcessing||this.queue.length===0)return;this.isProcessing=!0;let e=this.queue.shift();this.commandTimeout>0&&(this.timeoutId=setTimeout(()=>{this.timeoutId=null,this.onTimeout(e),this.advance()},this.commandTimeout)),this.onSend(e).catch(()=>{this.advance()})}clearCommandTimeout(){this.timeoutId!==null&&(clearTimeout(this.timeoutId),this.timeoutId=null)}},i=class e extends Error{constructor(t){super(t),this.name=`SerialPortConflictError`,Object.setPrototypeOf(this,e.prototype)}},a=class e extends Error{constructor(t){super(t),this.name=`SerialPermissionError`,Object.setPrototypeOf(this,e.prototype)}},o=class e extends Error{constructor(t){super(t),this.name=`SerialTimeoutError`,Object.setPrototypeOf(this,e.prototype)}},s=class e extends Error{constructor(t){super(t),this.name=`SerialReadError`,Object.setPrototypeOf(this,e.prototype)}},c=class e extends Error{constructor(t){super(t),this.name=`SerialWriteError`,Object.setPrototypeOf(this,e.prototype)}},l=class e extends t{port=null;reader=null;writer=null;queue;options;isConnecting=!1;abortController=null;userInitiatedDisconnect=!1;reconnectTimerId=null;isHandshaking=!1;static customProvider=null;static polyfillOptions;constructor(e){super(),this.options={baudRate:e.baudRate,dataBits:e.dataBits??8,stopBits:e.stopBits??1,parity:e.parity??`none`,bufferSize:e.bufferSize??255,flowControl:e.flowControl??`none`,filters:e.filters??[],commandTimeout:e.commandTimeout??0,parser:e.parser,autoReconnect:e.autoReconnect??!1,autoReconnectInterval:e.autoReconnectInterval??1500,handshakeTimeout:e.handshakeTimeout??2e3,provider:e.provider,polyfillOptions:e.polyfillOptions},this.queue=new r({commandTimeout:this.options.commandTimeout,onSend:async e=>{await this.writeToPort(e),this.emit(`serial:sent`,e,this)},onTimeout:e=>{this.emit(`serial:timeout`,e,this)}}),this.on(`serial:data`,()=>{this.queue.advance()}),n.register(this)}async handshake(){return!0}async connect(){if(!this.isConnecting&&!this.port){this.isConnecting=!0,this.emit(`serial:connecting`,this);try{let t=this.getSerial();if(!t)throw Error(`Web Serial API is not supported in this browser. Use AbstractSerialDevice.setProvider() to set a WebUSB polyfill.`);if(this.port=await this.findAndValidatePort(),!this.port){let n;try{n=await t.requestPort({filters:this.options.filters},this.options.polyfillOptions??e.polyfillOptions)}catch(e){throw e instanceof DOMException&&(e.name===`NotFoundError`||e.name===`SecurityError`||e.name===`AbortError`)?new a(e instanceof Error?e.message:String(e)):e instanceof Error?e:Error(String(e))}if(!await this.openAndHandshake(n))throw Error(`Handshake failed: the selected device did not respond correctly.`);this.port=n}this.abortController=new AbortController,this.queue.resume(),this.emit(`serial:connected`,this)}catch(e){if(e instanceof a?this.emit(`serial:need-permission`,this):this.emit(`serial:error`,e instanceof Error?e:Error(String(e)),this),this.port){n.unlockPort(this.port);try{await this.port.close()}catch{}this.port=null}throw e}finally{this.isConnecting=!1}}}async disconnect(){this.port&&(this.userInitiatedDisconnect=!0,this.stopReconnecting(),await this.cleanupPort())}isConnected(){return!!(this.port&&this.port.connected&&this.port.readable&&this.port.writable)}isDisconnected(){return!this.isConnected()}async cleanupPort(){if(this.port){this.queue.pause(),this.abortController?.abort(),this.abortController=null;try{let e=this.reader,t=this.writer;if(this.reader=null,this.writer=null,e){try{await e.cancel()}catch{}try{e.releaseLock()}catch{}}if(t){try{await t.close()}catch{}try{t.releaseLock()}catch{}}try{await this.port.close()}catch{}}catch(e){this.emit(`serial:error`,e instanceof Error?e:Error(String(e)),this)}finally{this.port&&n.unlockPort(this.port),this.port=null,this.options.parser?.reset?.(),this.emit(`serial:disconnected`,this),!this.userInitiatedDisconnect&&this.options.autoReconnect&&this.startReconnecting(),this.userInitiatedDisconnect=!1}}}async forget(){await this.disconnect(),this.port&&typeof this.port.forget==`function`&&await this.port.forget(),n.unregister(this)}async send(e){let t;t=typeof e==`string`?new TextEncoder().encode(e):e,t.length>0&&this.queue.enqueue(t)}clearQueue(){this.queue.clear(),this.emit(`serial:queue-empty`,this)}async writeToPort(e){if(!this.port||!this.port.writable)throw new c(`Port not writable.`);this.writer=this.port.writable.getWriter();try{await this.writer.write(e)}catch(e){throw new c(e instanceof Error?e.message:String(e))}finally{this.writer.releaseLock(),this.writer=null}}async readLoop(){if(!(!this.port||!this.port.readable)&&!this.reader){this.reader=this.port.readable.getReader();try{for(;;){let{value:e,done:t}=await this.reader.read();if(t)break;e&&(this.options.parser?this.options.parser.parse(e,e=>{this.emit(`serial:data`,e,this)}):this.emit(`serial:data`,e,this))}}catch(e){if(this.port)throw new s(e instanceof Error?e.message:String(e))}finally{if(this.reader){try{this.reader.releaseLock()}catch{}this.reader=null}}}}async openAndHandshake(e){let t=this;if(n.isPortInUse(e,t))return!1;n.lockPort(e,t);try{await e.open({baudRate:this.options.baudRate,dataBits:this.options.dataBits,stopBits:this.options.stopBits,parity:this.options.parity,bufferSize:this.options.bufferSize,flowControl:this.options.flowControl})}catch(t){throw n.unlockPort(e),t instanceof Error?t:Error(String(t))}this.port=e,this.abortController=new AbortController;let r=this.queue.snapshot();this.isHandshaking=!0,this.readLoop().catch(e=>{!this.isHandshaking&&this.port&&(this.emit(`serial:error`,e,this),this.cleanupPort())}),this.queue.resume();try{let t=await this.runHandshakeWithTimeout();return this.isHandshaking=!1,t?(this.queue.pause(),this.queue.clear(),this.queue.restore(r),this.options.parser?.reset?.(),!0):(await this.teardownHandshake(e,r),!1)}catch{return this.isHandshaking=!1,await this.teardownHandshake(e,r),!1}}async teardownHandshake(e,t){this.queue.pause(),this.queue.clear(),this.queue.restore(t),await this.stopReader(),this.port=null,this.abortController=null,this.options.parser?.reset?.();try{await e.close()}catch{}n.unlockPort(e)}async stopReader(){let e=this.reader;if(this.reader=null,e){try{await e.cancel()}catch{}try{e.releaseLock()}catch{}}}async runHandshakeWithTimeout(){let e=this.options.handshakeTimeout??2e3;return Promise.race([this.handshake(),new Promise(t=>setTimeout(()=>t(!1),e))])}async findAndValidatePort(){let t=this.getSerial();if(!t)return null;let r=await t.getPorts(this.options.polyfillOptions??e.polyfillOptions);if(r.length===0)return null;let i=this.options.filters??[],a=this;for(let e of r)if(!n.isPortInUse(e,a)){if(i.length>0){let t=e.getInfo();if(!i.some(e=>{let n=e.usbVendorId===void 0||e.usbVendorId===t.usbVendorId,r=e.usbProductId===void 0||e.usbProductId===t.usbProductId;return n&&r}))continue}try{if(await this.openAndHandshake(e))return e}catch{}}return null}startReconnecting(){this.reconnectTimerId||=(this.emit(`serial:reconnecting`,this),setInterval(async()=>{if(this.port||this.isConnecting){this.stopReconnecting();return}try{let e=await this.findAndValidatePort();e&&(this.stopReconnecting(),await this.reconnect(e))}catch{}},this.options.autoReconnectInterval))}stopReconnecting(){this.reconnectTimerId&&=(clearInterval(this.reconnectTimerId),null)}async reconnect(e){if(!(this.isConnecting||this.port)){this.isConnecting=!0,this.emit(`serial:connecting`,this);try{this.port=e,this.abortController=new AbortController,this.queue.resume(),this.emit(`serial:connected`,this)}catch(e){this.emit(`serial:error`,e instanceof Error?e:Error(String(e)),this),this.port&&=(n.unlockPort(this.port),null),this.options.autoReconnect&&this.startReconnecting()}finally{this.isConnecting=!1}}}static getInstances(){return n.getInstances()}static async connectAll(){let e=n.getInstances();for(let t of e)try{await t.connect()}catch{}}static setProvider(t,n){e.customProvider=t,e.polyfillOptions=n}getSerial(){return this.options.provider?this.options.provider:e.customProvider?e.customProvider:typeof navigator<`u`&&navigator.serial?navigator.serial:null}};function u(e=50){let t=new Uint8Array,n=null;function r(e){for(;!(t.length<2);){let n=t[1]+5;if(t.length<n)break;e(t.slice(0,n)),t=t.slice(n)}}return{parse(i,a){n!==null&&(clearTimeout(n),n=null);let o=new Uint8Array(t.length+i.length);o.set(t),o.set(i,t.length),t=o,r(a),t.length>0&&(n=setTimeout(()=>{t=new Uint8Array,n=null},e))},reset(){n!==null&&(clearTimeout(n),n=null),t=new Uint8Array}}}function d(e){return typeof e==`string`?new TextEncoder().encode(e):e instanceof Uint8Array?e:new Uint8Array(e)}function f(e,t){if(t.length===0)return 0;outer:for(let n=0;n<=e.length-t.length;n++){for(let r=0;r<t.length;r++)if(e[n+r]!==t[r])continue outer;return n}return-1}function p(e,t){let n=t?.includeDelimiter??!1,r=d(e);if(typeof e==`string`){let e=new Uint8Array,t=new TextDecoder;return{parse(i,a){let o=new Uint8Array(e.length+i.length);o.set(e),o.set(i,e.length),e=o;let s;for(;(s=f(e,r))!==-1;){let i=n?s+r.length:s;a(t.decode(e.slice(0,i))),t=new TextDecoder,e=e.slice(s+r.length)}},reset(){e=new Uint8Array,t=new TextDecoder}}}let i=new Uint8Array;return{parse(e,t){let a=new Uint8Array(i.length+e.length);a.set(i),a.set(e,i.length),i=a;let o;for(;(o=f(i,r))!==-1;){let e=n?o+r.length:o;t(i.slice(0,e)),i=i.slice(o+r.length)}},reset(){i=new Uint8Array}}}function m(e){if(e<=0)throw Error(`FixedLengthParser: length must be greater than 0`);let t=new Uint8Array;return{parse(n,r){let i=new Uint8Array(t.length+n.length);for(i.set(t),i.set(n,t.length),t=i;t.length>=e;)r(t.slice(0,e)),t=t.slice(e)},reset(){t=new Uint8Array}}}function h(e){if(e.interval<=0)throw Error(`InterByteTimeoutParser: interval must be greater than 0`);let t=e.maxBufferSize??65536,n=new Uint8Array,r=null,i=null;function a(){r!==null&&(clearTimeout(r),r=null),n.length>0&&i!==null&&(i(n.slice()),n=new Uint8Array)}return{parse(o,s){i=s,r!==null&&(clearTimeout(r),r=null);let c=new Uint8Array(n.length+o.length);if(c.set(n),c.set(o,n.length),n=c,n.length>=t){a();return}r=setTimeout(()=>{r=null,a()},e.interval)},reset(){r!==null&&(clearTimeout(r),r=null),n=new Uint8Array,i=null}}}function g(e){let t=e?.delimiter??170,n=e?.packetOverhead??2,r=e?.lengthBytes??1,i=e?.lengthOffset??1,a=e?.maxLen??255;if(i+r>n)throw Error(`PacketLengthParser: lengthOffset + lengthBytes must not exceed packetOverhead`);let o=new Uint8Array;return{parse(e,s){let c=new Uint8Array(o.length+e.length);for(c.set(o),c.set(e,o.length),o=c;;){let e=o.indexOf(t);if(e===-1){o=new Uint8Array;break}e>0&&(o=o.slice(e));let c=i+r;if(o.length<c)break;let l=0;for(let e=0;e<r;e++)l=l<<8|o[i+e];if(l>a){o=o.slice(1);continue}let u=l+n;if(o.length<u)break;s(o.slice(0,u)),o=o.slice(u)}},reset(){o=new Uint8Array}}}function _(){return{parse(e,t){t(e)},reset(){}}}function v(e,t){if(t.length===0)return 0;outer:for(let n=0;n<=e.length-t.length;n++){for(let r=0;r<t.length;r++)if(e[n+r]!==t[r])continue outer;return n}return-1}function y(e){let t=e?.encoding??`utf-8`,n=e?.includeDelimiter??!1,r=e?.delimiter??`
2
+ `,i;i=typeof r==`string`?new TextEncoder().encode(r):r instanceof Uint8Array?r:new Uint8Array(r);let a=new Uint8Array;return{parse(e,r){let o=new Uint8Array(a.length+e.length);o.set(a),o.set(e,a.length),a=o;let s;for(;(s=v(a,i))!==-1;){let e=n?s+i.length:s;r(new TextDecoder(t).decode(a.slice(0,e))),a=a.slice(s+i.length)}},reset(){a=new Uint8Array}}}function b(e,t){if(t.length===0)return 0;outer:for(let n=0;n<=e.length-t.length;n++){for(let r=0;r<t.length;r++)if(e[n+r]!==t[r])continue outer;return n}return-1}function x(e){let t=e.delimiter,n;n=typeof t==`string`?new TextEncoder().encode(t):t instanceof Uint8Array?t:new Uint8Array(t);let r=!1,i=new Uint8Array;return{parse(t,a){if(r){a(t);return}let o=new Uint8Array(i.length+t.length);o.set(i),o.set(t,i.length),i=o;let s=b(i,n);if(s===-1)return;r=!0,e.onReady?.();let c=i.slice(s+n.length);i=new Uint8Array,c.length>0&&a(c)},reset(){r=!1,i=new Uint8Array}}}function S(e){let t=e.regex instanceof RegExp?e.regex:new RegExp(e.regex),n=e.encoding??`utf-8`,r=``;return{parse(e,i){let a=new TextDecoder(n);r+=a.decode(e);let o=r.split(t);r=o.pop()??``;for(let e of o)i(e)},reset(){r=``}}}var C={END:192,ESC:219,ESC_END:220,ESC_ESC:221};function ee(e){let t=e?.END??C.END,n=e?.ESC??C.ESC,r=e?.ESC_END??C.ESC_END,i=e?.ESC_ESC??C.ESC_ESC,a=e?.START,o=e?.ESC_START??n,s=[],c=!1,l=a===void 0;return{parse(e,u){for(let d=0;d<e.length;d++){let f=e[d];if(!l){f===a&&(l=!0);continue}if(f===t){s.length>0&&(u(new Uint8Array(s)),s=[]),a!==void 0&&(l=!1),c=!1;continue}if(c){c=!1,f===r?s.push(t):f===i?s.push(n):a!==void 0&&f===o?s.push(a):s.push(f);continue}if(f===n){c=!0;continue}s.push(f)}},reset(){s=[],c=!1,l=a===void 0}}}function w(e,t){let n=t?.END??C.END,r=t?.ESC??C.ESC,i=t?.ESC_END??C.ESC_END,a=t?.ESC_ESC??C.ESC_ESC,o=t?.START,s=t?.ESC_START??r,c=t?.bluetoothQuirk??!1,l=[];c&&l.push(n);for(let t=0;t<e.length;t++){let c=e[t];c===n?l.push(r,i):c===r?l.push(r,a):o!==void 0&&c===o?l.push(r,s):l.push(c)}return l.push(n),new Uint8Array(l)}function T(e){let t=e?.timeCodeFieldLength??0,n=e?.ancillaryDataFieldLength??0,r=new Uint8Array;function i(e){let r=e[0],i=e[1],a=e[2],o=e[3],s=e[4],c=e[5],l=r>>5&7,u=r>>4&1,d=r>>3&1,f=(r&7)<<8|i,p=a>>6&3,m=(a&63)<<8|o,h=s<<8|c,g={versionNumber:l,identification:{apid:f,secondaryHeader:d,type:u},sequenceControl:{packetName:m,sequenceFlags:p},dataLength:h},_,v=6;if(d===1){_={};let r=new TextDecoder(`latin1`);t>0&&(_.timeCode=r.decode(e.slice(v,v+t)),v+=t),n>0&&(_.ancillaryData=r.decode(e.slice(v,v+n)),v+=n)}let y=new TextDecoder(`latin1`).decode(e.slice(v));return{header:g,secondaryHeader:_,data:y}}return{parse(e,t){let n=new Uint8Array(r.length+e.length);for(n.set(r),n.set(e,r.length),r=n;r.length>=6;){let e=6+(r[4]<<8|r[5])+1;if(r.length<e)break;t(i(r.slice(0,e))),r=r.slice(e)}},reset(){r=new Uint8Array}}}var E=32,D=34,O=0,k=30,A=3,j=7,te=1,ne=0,re=771,ie=768,M=255,N=8,P=`none`,F=1,I=[16,8,7,6,5],L=[1,2],R=[`none`,`even`,`odd`],z=[`none`,`odd`,`even`],B=[1,1.5,2],V={usbControlInterfaceClass:2,usbTransferInterfaceClass:10,protocol:void 0};function H(e,t){let n=e.configurations[0];if(!n)return null;for(let e of n.interfaces)if(e.alternates[0]?.interfaceClass===t)return e;return null}function U(e,t){let n=e.configurations[0];if(!n)return null;for(let e of n.interfaces){let n=e.alternates[0];if(!n||n.interfaceClass!==t)continue;let r=n.endpoints.some(e=>e.direction===`in`),i=n.endpoints.some(e=>e.direction===`out`);if(r&&i)return e}return null}function W(e,t){let n=e.alternates[0];if(n){for(let e of n.endpoints)if(e.direction===t)return e}throw TypeError(`Interface ${e.interfaceNumber} does not have an ${t} endpoint.`)}function G(e,t){return t===2?`cdc_acm`:e.vendorId===4292?`cp210x`:`none`}var K=class{device_;endpoint_;onError_;constructor(e,t,n){this.device_=e,this.endpoint_=t,this.onError_=n}pull(e){(async()=>{let t=this.endpoint_.packetSize;try{let n=await this.device_.transferIn(this.endpoint_.endpointNumber,t);if(n.status!==`ok`){e.error(`USB error: ${n.status}`),this.onError_();return}if(n.data?.buffer&&n.data.byteLength>0){let t=new Uint8Array(n.data.buffer,n.data.byteOffset,n.data.byteLength);t.length>0&&e.enqueue(t)}}catch(t){e.error(String(t)),this.onError_()}})()}},q=class{device_;endpoint_;onError_;constructor(e,t,n){this.device_=e,this.endpoint_=t,this.onError_=n}async write(e,t){try{let n=await this.device_.transferOut(this.endpoint_.endpointNumber,e.buffer);n.status!==`ok`&&(t.error(n.status),this.onError_())}catch(e){t.error(String(e)),this.onError_()}}},J=class{device_;protocol_;controlInterface_;transferInterface_;inEndpoint_;outEndpoint_;serialOptions_;readable_=null;writable_=null;cdcOutputSignals_={dataTerminalReady:!1,requestToSend:!1,break:!1};constructor(e,t){this.device_=e;let n={...V,...t};this.protocol_=n.protocol??G(e,n.usbControlInterfaceClass);let r=n.usbControlInterfaceClass,i=n.usbTransferInterfaceClass;if(r===i){let t=U(e,i);if(!t)throw TypeError(`Unable to find interface with class ${i} that has both IN and OUT endpoints.`);this.controlInterface_=t,this.transferInterface_=t}else{let t=H(e,r);if(!t)throw TypeError(`Unable to find control interface with class ${r}.`);let n=U(e,i)??H(e,i);if(!n)throw TypeError(`Unable to find transfer interface with class ${i}.`);this.controlInterface_=t,this.transferInterface_=n}this.inEndpoint_=W(this.transferInterface_,`in`),this.outEndpoint_=W(this.transferInterface_,`out`)}get readable(){return!this.readable_&&this.device_.opened&&(this.readable_=new ReadableStream(new K(this.device_,this.inEndpoint_,()=>{this.readable_=null}),{highWaterMark:this.serialOptions_?.bufferSize??M})),this.readable_}get writable(){return!this.writable_&&this.device_.opened&&(this.writable_=new WritableStream(new q(this.device_,this.outEndpoint_,()=>{this.writable_=null}),new ByteLengthQueuingStrategy({highWaterMark:this.serialOptions_?.bufferSize??M}))),this.writable_}async open(e){this.serialOptions_=e,this.validateOptions();try{switch(await this.device_.open(),this.device_.configuration===null&&await this.device_.selectConfiguration(1),await this.device_.claimInterface(this.controlInterface_.interfaceNumber),this.controlInterface_!==this.transferInterface_&&await this.device_.claimInterface(this.transferInterface_.interfaceNumber),this.protocol_){case`cdc_acm`:await this.cdcInit();break;case`cp210x`:await this.cp210xInit();break;case`none`:break}}catch(e){throw this.device_.opened&&await this.device_.close(),Error(`Error setting up device: `+(e instanceof Error?e.message:String(e)),{cause:e})}}async close(){let e=[];if(this.readable_&&e.push(this.readable_.cancel()),this.writable_&&e.push(this.writable_.abort()),await Promise.all(e),this.readable_=null,this.writable_=null,this.device_.opened){switch(this.protocol_){case`cdc_acm`:await this.cdcSetSignals({dataTerminalReady:!1,requestToSend:!1});break;case`cp210x`:await this.cp210xDeinit();break}await this.device_.close()}}async forget(){return this.device_.forget()}getInfo(){return{usbVendorId:this.device_.vendorId,usbProductId:this.device_.productId}}async cdcInit(){await this.cdcSetLineCoding(),await this.cdcSetSignals({dataTerminalReady:!0})}async cdcSetSignals(e){if(this.cdcOutputSignals_={...this.cdcOutputSignals_,...e},e.dataTerminalReady!==void 0||e.requestToSend!==void 0){let e=!!this.cdcOutputSignals_.dataTerminalReady|(this.cdcOutputSignals_.requestToSend?2:0);await this.device_.controlTransferOut({requestType:`class`,recipient:`interface`,request:D,value:e,index:this.controlInterface_.interfaceNumber})}}async cdcSetLineCoding(){let e=new ArrayBuffer(7),t=new DataView(e);if(t.setUint32(0,this.serialOptions_.baudRate,!0),t.setUint8(4,B.indexOf(this.serialOptions_.stopBits??F)),t.setUint8(5,z.indexOf(this.serialOptions_.parity??P)),t.setUint8(6,this.serialOptions_.dataBits??N),(await this.device_.controlTransferOut({requestType:`class`,recipient:`interface`,request:E,value:0,index:this.controlInterface_.interfaceNumber},e)).status!==`ok`)throw new DOMException(`Failed to set line coding.`,`NetworkError`)}async cp210xInit(){let e=this.controlInterface_.interfaceNumber;await this.device_.controlTransferOut({requestType:`vendor`,recipient:`interface`,request:O,value:te,index:e});let t=new ArrayBuffer(4);new DataView(t).setUint32(0,this.serialOptions_.baudRate,!0),await this.device_.controlTransferOut({requestType:`vendor`,recipient:`interface`,request:k,value:0,index:e},t);let n=this.serialOptions_.dataBits??N,r={none:0,odd:16,even:32}[this.serialOptions_.parity??P]??0,i=({1:0,2:2}[this.serialOptions_.stopBits??F]??0)<<8|r|n;await this.device_.controlTransferOut({requestType:`vendor`,recipient:`interface`,request:A,value:i,index:e}),await this.device_.controlTransferOut({requestType:`vendor`,recipient:`interface`,request:j,value:re,index:e})}async cp210xDeinit(){let e=this.controlInterface_.interfaceNumber;await this.device_.controlTransferOut({requestType:`vendor`,recipient:`interface`,request:j,value:ie,index:e}),await this.device_.controlTransferOut({requestType:`vendor`,recipient:`interface`,request:O,value:ne,index:e})}validateOptions(){if(this.serialOptions_.baudRate%1!=0)throw RangeError(`Invalid baud rate: ${this.serialOptions_.baudRate}`);if(this.serialOptions_.dataBits!==void 0&&!I.includes(this.serialOptions_.dataBits))throw RangeError(`Invalid dataBits: ${this.serialOptions_.dataBits}`);if(this.serialOptions_.stopBits!==void 0&&!L.includes(this.serialOptions_.stopBits))throw RangeError(`Invalid stopBits: ${this.serialOptions_.stopBits}`);if(this.serialOptions_.parity!==void 0&&!R.includes(this.serialOptions_.parity))throw RangeError(`Invalid parity: ${this.serialOptions_.parity}`)}},ae=class{options_;constructor(e){this.options_={...V,...e}}async requestPort(e,t){let n={...this.options_,...t},r=[];if(e?.filters&&e.filters.length>0)for(let t of e.filters){let e={};t.usbVendorId!==void 0&&(e.vendorId=t.usbVendorId),t.usbProductId!==void 0&&(e.productId=t.usbProductId),n.usbControlInterfaceClass!==void 0&&n.usbControlInterfaceClass!==255?e.classCode=n.usbControlInterfaceClass:e.vendorId===void 0&&e.productId===void 0&&(e.classCode=n.usbControlInterfaceClass??2),r.push(e)}else r.push({classCode:n.usbControlInterfaceClass??2});return new J(await navigator.usb.requestDevice({filters:r}),n)}async getPorts(e){let t={...this.options_,...e},n=await navigator.usb.getDevices(),r=[];for(let e of n)try{let n=new J(e,t);r.push(n)}catch{}return r}},Y=`6e400001-b5a3-f393-e0a9-e50e24dcca9e`,oe=`6e400003-b5a3-f393-e0a9-e50e24dcca9e`,se=`6e400002-b5a3-f393-e0a9-e50e24dcca9e`,X=20,ce=10;function le(e){let t=null,n=null,r=null;return{get readable(){return t},get writable(){return n},getInfo(){return{}},async open(){if(!e.gatt)throw Error(`GATT not available on this Bluetooth device.`);r=await e.gatt.connect();let i=await r.getPrimaryService(Y),a=await i.getCharacteristic(oe),o=await i.getCharacteristic(se);await a.startNotifications(),t=new ReadableStream({start(e){a.addEventListener(`characteristicvaluechanged`,t=>{let n=t.target.value.buffer;e.enqueue(new Uint8Array(n))})}}),n=new WritableStream({async write(e){for(let t=0;t<e.length;t+=X){let n=e.slice(t,t+X);await o.writeValueWithoutResponse(n),t+X<e.length&&await new Promise(e=>setTimeout(e,ce))}}})},async close(){r?.connected&&r.disconnect(),t=null,n=null}}}function ue(){return{async requestPort(){if(!navigator.bluetooth)throw Error(`Web Bluetooth API is not supported in this browser. Use Chrome on Android, macOS, or ChromeOS.`);return le(await navigator.bluetooth.requestDevice({filters:[{services:[Y]}]}))},async getPorts(){return[]}}}function Z(e){return new Promise((t,n)=>{e.addEventListener(`open`,()=>t(),{once:!0}),e.addEventListener(`error`,e=>n(e),{once:!0})})}function Q(e,t){return new Promise(n=>{let r=i=>{let a=JSON.parse(i.data);a.type===t&&(e.removeEventListener(`message`,r),n(a.payload))};e.addEventListener(`message`,r)})}function $(e,t){let n=null,r=null;return{get readable(){return n},get writable(){return r},getInfo(){return{usbVendorId:t.vendorId,usbProductId:t.productId}},async open(i){e.send(JSON.stringify({type:`open`,path:t.path,baudRate:i.baudRate,dataBits:i.dataBits,stopBits:i.stopBits,parity:i.parity,parser:{type:`delimiter`,value:`\\n`}})),await Q(e,`opened`);let a=[],o=null,s=!1;function c(e){let t=JSON.parse(e.data);if(t.type===`data`&&t.bytes){let e=new Uint8Array(t.bytes);o?o.enqueue(e):a.push(e)}t.type===`closed`&&(s=!0,o&&o.close())}e.addEventListener(`message`,c),n=new ReadableStream({start(e){o=e;for(let t of a)e.enqueue(t);a.length=0,s&&e.close()},cancel(){e.removeEventListener(`message`,c),o=null}}),r=new WritableStream({write(t){e.send(JSON.stringify({type:`write`,bytes:Array.from(t)}))}})},async close(){e.send(JSON.stringify({type:`close`})),n=null,r=null,e.close()}}}function de(e){return{async requestPort(t){let n=new WebSocket(e);await Z(n),n.send(JSON.stringify({type:`list-ports`,filters:t?.filters??[]}));let r=(await Q(n,`port-list`))[0];if(!r)throw Error(`No ports available on the bridge server. Make sure the Node.js server is running and a device is connected.`);return $(n,r)},async getPorts(){let t=new WebSocket(e);return await Z(t),t.send(JSON.stringify({type:`list-ports`,filters:[]})),(await Q(t,`port-list`)).map(e=>$(t,e))}}}e.AbstractSerialDevice=l,e.CommandQueue=r,e.SerialEventEmitter=t,e.SerialPermissionError=a,e.SerialPortConflictError=i,e.SerialReadError=s,e.SerialRegistry=n,e.SerialTimeoutError=o,e.SerialWriteError=c,e.WebUsbProvider=ae,e.ccTalk=u,e.createBluetoothProvider=ue,e.createWebSocketProvider=de,e.delimiter=p,e.fixedLength=m,e.interByteTimeout=h,e.packetLength=g,e.raw=_,e.readline=y,e.readyParser=x,e.regexParser=S,e.slipDecoder=ee,e.slipEncode=w,e.spacePacket=T});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webserial-core",
3
- "version": "2.0.3",
3
+ "version": "2.1.0",
4
4
  "author": "danidoble",
5
5
  "repository": {
6
6
  "type": "git",