webserial-core 1.2.0 → 2.0.0-dev.1
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.
- package/{LICENSE → LICENSE.md} +1 -1
- package/README.md +142 -287
- package/dist/adapters/web-bluetooth/WebBluetoothProvider.d.ts +19 -0
- package/dist/adapters/web-bluetooth/index.d.ts +6 -0
- package/dist/adapters/web-usb/WebUsbProvider.d.ts +127 -0
- package/dist/adapters/web-usb/index.d.ts +6 -0
- package/dist/adapters/websocket/WebSocketProvider.d.ts +20 -0
- package/dist/adapters/websocket/index.d.ts +6 -0
- package/dist/core/AbstractSerialDevice.d.ts +108 -0
- package/dist/core/SerialEventEmitter.d.ts +37 -0
- package/dist/core/SerialRegistry.d.ts +53 -0
- package/dist/errors/index.d.ts +40 -0
- package/dist/index.d.ts +10 -0
- package/dist/parsers/DelimiterParser.d.ts +22 -0
- package/dist/parsers/FixedLengthParser.d.ts +23 -0
- package/dist/parsers/RawParser.d.ts +22 -0
- package/dist/parsers/index.d.ts +7 -0
- package/dist/queue/CommandQueue.d.ts +98 -0
- package/dist/types/index.d.ts +124 -0
- package/dist/webserial-core.cjs +1 -0
- package/dist/webserial-core.mjs +853 -0
- package/dist/webserial-core.umd.js +1 -0
- package/package.json +62 -68
- package/dist/types/Core.d.ts +0 -268
- package/dist/types/Core.d.ts.map +0 -1
- package/dist/types/Devices.d.ts +0 -62
- package/dist/types/Devices.d.ts.map +0 -1
- package/dist/types/Dispatcher.d.ts +0 -98
- package/dist/types/Dispatcher.d.ts.map +0 -1
- package/dist/types/SerialError.d.ts +0 -61
- package/dist/types/SerialError.d.ts.map +0 -1
- package/dist/types/SerialEvent.d.ts +0 -4
- package/dist/types/SerialEvent.d.ts.map +0 -1
- package/dist/types/Socket.d.ts +0 -29
- package/dist/types/Socket.d.ts.map +0 -1
- package/dist/types/main.d.ts +0 -15
- package/dist/types/main.d.ts.map +0 -1
- package/dist/types/utils.d.ts +0 -3
- package/dist/types/utils.d.ts.map +0 -1
- package/dist/webserial-core.js +0 -1236
- package/dist/webserial-core.js.map +0 -1
- package/dist/webserial-core.umd.cjs +0 -5
- package/dist/webserial-core.umd.cjs.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"webserial-core.umd.cjs","sources":["../lib/SerialEvent.ts","../lib/Dispatcher.ts","../lib/Devices.ts","../lib/utils.ts","../lib/Socket.ts","../lib/Core.ts","../lib/SerialError.ts"],"sourcesContent":["export class SerialEvent extends CustomEvent<SerialEvent> implements CustomEvent {\n constructor(type: string, options: CustomEventInit) {\n super(type, options);\n }\n}\n","import { SerialEvent } from \"./SerialEvent\";\n\ntype AvailableListener = { type: string; listening: boolean };\ntype AvailableListeners = AvailableListener[];\n\ntype DataType = string | number | boolean | object | null;\n\ninterface IDispatcher {\n dispatch(type: string, data?: DataType): void;\n\n dispatchAsync(type: string, data?: DataType, ms?: number): void;\n\n on(type: string, callback: EventListener): void;\n\n off(type: string, callback: EventListener): void;\n\n serialRegisterAvailableListener(type: string): void;\n\n availableListeners: AvailableListeners;\n}\n\ninterface Listeners {\n [key: string]: boolean;\n\n debug: boolean;\n}\n\nexport class Dispatcher extends EventTarget implements IDispatcher {\n __listeners__: Listeners = {\n debug: false,\n };\n __debug__: boolean = false;\n\n __listenersCallbacks__: { key: string; callback: EventListenerOrEventListenerObject }[] = [];\n\n /**\n * Dispatches an event with the specified type and data\n * @param type - The event type to dispatch\n * @param data - Optional data to attach to the event\n * @example\n * ```typescript\n * dispatcher.dispatch('connected', { port: 'COM3' });\n * ```\n */\n public dispatch(type: string, data: DataType = null) {\n const event = new SerialEvent(type, { detail: data });\n this.dispatchEvent(event);\n if (this.__debug__) {\n this.dispatchEvent(new SerialEvent(\"debug\", { detail: { type, data } }));\n }\n }\n\n /**\n * Dispatches an event asynchronously after a specified delay\n * @param type - The event type to dispatch\n * @param data - Optional data to attach to the event\n * @param ms - Delay in milliseconds (default: 100)\n * @example\n * ```typescript\n * dispatcher.dispatchAsync('timeout', { reason: 'no response' }, 500);\n * ```\n */\n public dispatchAsync(type: string, data = null, ms = 100) {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const this1 = this;\n setTimeout(() => {\n this1.dispatch(type, data);\n }, ms);\n }\n\n /**\n * Registers an event listener for the specified event type\n * @param type - The event type to listen to\n * @param callback - The callback function to execute when the event is triggered\n * @example\n * ```typescript\n * dispatcher.on('connected', (event) => {\n * console.log('Device connected', event.detail);\n * });\n * ```\n */\n public on(type: string, callback: EventListenerOrEventListenerObject) {\n if (typeof this.__listeners__[type] !== \"undefined\" && !this.__listeners__[type]) {\n this.__listeners__[type] = true;\n }\n\n this.__listenersCallbacks__.push({ key: type, callback });\n this.addEventListener(type, callback);\n }\n\n /**\n * Removes an event listener for the specified event type\n * @param type - The event type to stop listening to\n * @param callback - The callback function to remove\n * @example\n * ```typescript\n * const handler = (event) => console.log(event.detail);\n * dispatcher.on('data', handler);\n * dispatcher.off('data', handler);\n * ```\n */\n public off(type: string, callback: EventListenerOrEventListenerObject) {\n this.__listenersCallbacks__ = this.__listenersCallbacks__.filter((listener) => {\n return !(listener.key === type && listener.callback === callback);\n });\n\n this.removeEventListener(type, callback);\n }\n\n /**\n * Registers an available listener type for tracking\n * @param type - The event type to register\n * @internal\n */\n public serialRegisterAvailableListener(type: string) {\n if (this.__listeners__[type]) return;\n\n this.__listeners__[type] = false;\n }\n\n /**\n * Gets the list of all available listeners and their state\n * @returns Array of listener objects with type and listening status\n * @example\n * ```typescript\n * const listeners = dispatcher.availableListeners;\n * console.log(listeners); // [{ type: 'connected', listening: true }, ...]\n * ```\n */\n get availableListeners(): AvailableListeners {\n const keys = Object.keys(this.__listeners__).sort();\n return keys.map((type): AvailableListener => {\n return {\n type,\n listening: this.__listeners__[type],\n };\n });\n }\n\n /**\n * Removes all event listeners except internal ones (like queue listeners)\n * Resets all listener states to false\n * @example\n * ```typescript\n * dispatcher.removeAllListeners();\n * ```\n */\n public removeAllListeners(): void {\n for (const listener of this.__listenersCallbacks__) {\n if ([\"internal:queue\"].includes(listener.key)) continue; // Skip queue listener\n\n this.__listenersCallbacks__ = this.__listenersCallbacks__.filter((l) => {\n return !(l.key === listener.key && l.callback === listener.callback);\n });\n this.removeEventListener(listener.key, listener.callback);\n }\n for (const key of Object.keys(this.__listeners__)) {\n this.__listeners__[key] = false;\n }\n }\n}\n","import { Core } from \"./Core\";\nimport { Dispatcher } from \"./Dispatcher\";\n\ninterface IDevice {\n [key: string]: Core;\n}\n\ninterface IDevices {\n [key: string]: IDevice;\n}\n\n/**\n * Manages and tracks all serial devices in the application\n * Provides a centralized registry for device instances\n * @extends Dispatcher\n */\nexport class Devices extends Dispatcher {\n static instance: Devices;\n static devices: IDevices = {};\n\n constructor() {\n super();\n\n const availableListeners: string[] = [\"change\"];\n\n availableListeners.forEach((event: string): void => {\n this.serialRegisterAvailableListener(event);\n });\n }\n\n public static $dispatchChange(device: Core | null = null): void {\n if (device) {\n device.$checkAndDispatchConnection();\n }\n Devices.instance.dispatch(\"change\", { devices: Devices.devices, dispatcher: device });\n }\n\n public static typeError(type: string): void {\n const error = new Error();\n error.message = `Type ${type} is not supported`;\n error.name = \"DeviceTypeError\";\n throw error;\n }\n\n /**\n * Registers a new device type in the registry\n * @param type - The type name of the device (e.g., 'arduino', 'esp32')\n * @internal\n */\n public static registerType(type: string): void {\n if (typeof Devices.devices[type] === \"undefined\") {\n Devices.devices = { ...Devices.devices, [type]: {} };\n }\n }\n\n /**\n * Adds a device to the registry\n * @param device - The Core device instance to add\n * @returns The index of the device in its type registry\n * @throws {Error} If device with the same ID already exists\n * @example\n * ```typescript\n * const arduino = new Arduino();\n * Devices.add(arduino);\n * ```\n */\n public static add(device: Core): number {\n const type = device.typeDevice;\n if (typeof Devices.devices[type] === \"undefined\") {\n Devices.registerType(type);\n }\n\n const id: string = device.uuid;\n\n if (typeof Devices.devices[type] === \"undefined\") Devices.typeError(type);\n\n if (Devices.devices[type][id]) {\n throw new Error(`Device with id ${id} already exists`);\n }\n\n Devices.devices[type][id] = device;\n\n Devices.$dispatchChange(device);\n return Object.keys(Devices.devices[type]).indexOf(id);\n }\n\n /**\n * Gets a specific device by type and UUID\n * @param type - The device type\n * @param id - The device UUID\n * @returns The device instance\n * @throws {Error} If the device type is not supported\n * @example\n * ```typescript\n * const device = Devices.get('arduino', 'uuid-123');\n * ```\n */\n public static get(type: string, id: string): Core {\n if (typeof Devices.devices[type] === \"undefined\") {\n Devices.registerType(type);\n }\n\n if (typeof Devices.devices[type] === \"undefined\") Devices.typeError(type);\n\n return Devices.devices[type][id];\n }\n\n public static getAll(type: string | null = null): IDevice | IDevices {\n if (type === null) return Devices.devices;\n if (typeof Devices.devices[type] === \"undefined\") Devices.typeError(type);\n\n return Devices.devices[type];\n }\n\n public static getList(): Core[] {\n // get all devices in list mode no matter the type\n // by some reason the array is empty so we need to use Object.values and map\n const devices: IDevice[] = Object.values(Devices.devices);\n return devices\n .map((device: IDevice): Core[] => {\n return Object.values(device);\n })\n .flat();\n }\n\n public static getByNumber(type: string, device_number: number): Core | null {\n if (typeof Devices.devices[type] === \"undefined\") Devices.typeError(type);\n\n const devices = Object.values(Devices.devices[type]);\n return devices.find((device) => device.deviceNumber === device_number) ?? null;\n }\n\n public static getCustom(type: string, device_number: number = 1): Core | null {\n if (typeof Devices.devices[type] === \"undefined\") Devices.typeError(type);\n\n const devices = Object.values(Devices.devices[type]);\n return devices.find((device) => device.deviceNumber === device_number) ?? null;\n }\n\n public static async connectToAll(): Promise<boolean> {\n const devices: Core[] = Devices.getList();\n\n for (const device of devices) {\n if (device.isConnected) continue;\n await device.connect().catch(console.warn);\n }\n\n return Promise.resolve(Devices.areAllConnected());\n }\n\n public static async disconnectAll(): Promise<boolean> {\n const devices: Core[] = Devices.getList();\n\n for (const device of devices) {\n if (device.isDisconnected) continue;\n await device.disconnect().catch(console.warn);\n }\n\n return Promise.resolve(Devices.areAllDisconnected());\n }\n\n public static async areAllConnected(): Promise<boolean> {\n const devices: Core[] = Devices.getList();\n\n for (const device of devices) {\n if (!device.isConnected) return Promise.resolve(false);\n }\n\n return Promise.resolve(true);\n }\n\n public static async areAllDisconnected(): Promise<boolean> {\n const devices: Core[] = Devices.getList();\n\n for (const device of devices) {\n if (!device.isDisconnected) return Promise.resolve(false);\n }\n\n return Promise.resolve(true);\n }\n\n public static async getAllConnected(): Promise<Core[]> {\n const devices: Core[] = Devices.getList();\n return Promise.resolve(devices.filter((device: Core): boolean => device.isConnected));\n }\n\n public static async getAllDisconnected(): Promise<Core[]> {\n const devices: Core[] = Devices.getList();\n return Promise.resolve(devices.filter((device: Core): boolean => device.isDisconnected));\n }\n}\n\nif (!Devices.instance) {\n Devices.instance = new Devices();\n}\n","type empty = void | PromiseLike<void>;\n\nexport function wait(ms: number = 100): Promise<void> {\n return new Promise(\n (resolve: (value: empty) => void): ReturnType<typeof setTimeout> => setTimeout((): void => resolve(), ms),\n );\n}\n\n/*\n * @deprecated This function is deprecated and will be removed in future versions.\n */\nexport function supportWebSerial(): boolean {\n return \"serial\" in navigator;\n}\n","import { io, ManagerOptions, SocketOptions, Socket as SocketIOClient } from \"socket.io-client\";\nimport { Devices } from \"./Devices\";\nimport { Core } from \"./Core\";\n\ninterface SocketResponseData {\n name: string;\n uuid: string;\n deviceNumber: number;\n [key: string]: unknown;\n}\n\ntype BoundedFunction = {\n onResponse: (data: SocketResponseData) => void;\n onDisconnect: () => void;\n onConnect: () => void;\n onConnectError: (error: unknown) => void;\n};\n\nclass MySocket {\n #uri: string = \"http://localhost:3001\";\n #options: Partial<ManagerOptions & SocketOptions> = {\n transports: [\"websocket\"],\n };\n #socket: SocketIOClient | null = null;\n #connected: boolean = false;\n #hasInstance: boolean = false;\n\n #boundedFun: BoundedFunction;\n\n constructor(uri?: string, options?: Partial<ManagerOptions & SocketOptions>) {\n if (uri) {\n this.#uri = uri;\n }\n if (options) {\n this.#options = { ...this.#options, ...options };\n }\n\n this.#boundedFun = {\n onResponse: this.onResponse.bind(this),\n onDisconnect: () => {\n // console.debug(\"Socket disconnected\", this.#socket?.id);\n this.#connected = false;\n window.dispatchEvent(new Event(\"serial:socket:disconnected\"));\n },\n onConnect: () => {\n // console.debug(\"Socket connected\", this.#socket?.id);\n this.#connected = true;\n window.dispatchEvent(new Event(\"serial:socket:connected\"));\n },\n onConnectError: (error) => {\n console.debug(\"Socket connection error\", error);\n this.#connected = false;\n window.dispatchEvent(new Event(\"serial:socket:disconnected\"));\n },\n };\n }\n\n set uri(uri: string) {\n const url = new URL(uri);\n\n if (![\"http:\", \"https:\", \"ws:\", \"wss:\"].includes(url.protocol)) {\n throw new Error(\"URI must start with http://, https://, ws://, or wss://\");\n }\n this.#uri = uri;\n }\n\n get uri(): string {\n return this.#uri;\n }\n\n set options(options: Partial<ManagerOptions & SocketOptions>) {\n if (typeof options !== \"object\") {\n throw new Error(\"Options must be an object\");\n }\n this.#options = options;\n }\n\n get options(): Partial<ManagerOptions & SocketOptions> {\n return this.#options;\n }\n\n get socketId(): string | null {\n return this.#socket && this.#socket.id ? this.#socket.id : null;\n }\n\n configure(uri?: string, options?: Partial<ManagerOptions & SocketOptions>): void {\n if (this.#hasInstance) {\n throw new Error(\"Cannot configure socket after it has been initialized. Call configure() before prepare().\");\n }\n if (uri) {\n this.uri = uri;\n }\n if (options) {\n this.#options = { ...this.#options, ...options };\n }\n }\n\n disconnect() {\n if (this.#socket) {\n this.#socket.off(\"response\", this.#boundedFun.onResponse);\n this.#socket.off(\"disconnect\", this.#boundedFun.onDisconnect);\n this.#socket.off(\"connect\", this.#boundedFun.onConnect);\n this.#socket.off(\"connect_error\", this.#boundedFun.onConnectError);\n\n this.#socket.disconnect();\n this.#socket = null;\n this.#hasInstance = false;\n }\n this.#connected = false;\n }\n\n prepare() {\n if (this.#connected || this.#hasInstance) return;\n\n this.#socket = io(this.#uri, this.#options);\n // this.#connected = true; // don't asume connected until onConnect is called\n this.#hasInstance = true;\n\n this.#socket.on(\"disconnect\", this.#boundedFun.onDisconnect);\n this.#socket.on(\"response\", this.#boundedFun.onResponse);\n this.#socket.on(\"connect\", this.#boundedFun.onConnect);\n this.#socket.on(\"connect_error\", this.#boundedFun.onConnectError);\n }\n\n connectDevice(config: object): void {\n if (!this.#socket) {\n throw new Error(\"Socket not connected. Call prepare() first.\");\n }\n this.#socket.emit(\"connectDevice\", { config });\n }\n\n disconnectDevice(config: object): void {\n if (!this.#socket) {\n throw new Error(\"Socket not connected. Call prepare() first.\");\n }\n this.#socket.emit(\"disconnectDevice\", { config });\n }\n\n disconnectAllDevices(): void {\n if (!this.#socket) {\n throw new Error(\"Socket not connected. Call prepare() first.\");\n }\n this.#socket.emit(\"disconnectAll\");\n }\n\n write(data: object): void {\n if (!this.#socket) {\n throw new Error(\"Socket not connected. Call prepare() first.\");\n }\n this.#socket.emit(\"cmd\", data);\n }\n\n onResponse(data: SocketResponseData): void {\n let device: Core | null = Devices.get(data.name, data.uuid);\n if (!device) {\n device = Devices.getByNumber(data.name, data.deviceNumber);\n }\n if (!device) {\n return;\n }\n device.socketResponse(data);\n }\n\n isConnected(): boolean {\n return this.#connected;\n }\n\n isDisconnected(): boolean {\n return !this.#connected;\n }\n}\n\nexport const Socket = new MySocket();\n","import { Dispatcher } from \"./Dispatcher\";\nimport { Devices } from \"./Devices\";\nimport { wait } from \"./utils\";\nimport { Socket } from \"./Socket\";\n\ninterface LastError {\n message: string | null;\n action: string | null;\n code: string | Uint8Array | Array<string> | Array<number> | null | number;\n no_code: number;\n}\n\ninterface DeviceData {\n type: string;\n id: string;\n listen_on_port: number | null;\n}\n\ntype SerialResponseAs = \"hex\" | \"uint8\" | \"string\" | \"arraybuffer\";\n\ninterface SerialResponse {\n length: number | null;\n buffer: Uint8Array;\n as: SerialResponseAs;\n replacer: RegExp | string;\n limiter: null | string | RegExp;\n prefixLimiter: boolean; // If true, the limiter is at the beginning of the message\n sufixLimiter: boolean; // If true, the limiter is at the end of the message\n delimited: boolean;\n}\n\ninterface QueueData {\n bytes: string | Uint8Array | Array<string> | Array<number>;\n action: string;\n}\n\ntype ParserSocketPort = {\n name: \"byte-length\" | \"inter-byte-timeout\";\n length?: number; // Length of each byte in the response, only for byte-length\n interval?: number; // Interval in milliseconds for inter-byte-timeout\n};\n\ntype PortInfo = {\n path: string | null;\n vendorId: number | string | null;\n productId: number | string | null;\n parser: ParserSocketPort;\n};\n\ntype SerialData = {\n transformStream: false | TransformStream;\n socket: boolean;\n portInfo: PortInfo;\n aux_connecting: string;\n connecting: boolean;\n connected: boolean;\n port: SerialPort | null;\n last_action: string | null;\n response: SerialResponse;\n reader: ReadableStreamDefaultReader<Uint8Array> | null;\n input_done: Promise<void> | null;\n output_done: Promise<void> | null;\n input_stream: ReadableStream<Uint8Array> | null;\n output_stream: WritableStream<Uint8Array> | null;\n keep_reading: boolean;\n time_until_send_bytes: number | undefined | ReturnType<typeof setTimeout>;\n delay_first_connection: number;\n bytes_connection: string | Uint8Array | string[] | number[] | null;\n filters: SerialPortFilter[];\n config_port: SerialOptions;\n queue: QueueData[];\n running_queue: boolean;\n auto_response: any;\n free_timeout_ms: number;\n useRTSCTS: boolean;\n};\n\ninterface TimeResponse {\n response_connection: number;\n response_engines: number;\n response_general: number;\n}\n\ninterface Timeout {\n until_response: number | ReturnType<typeof setTimeout>;\n}\n\ninterface InternalIntervals {\n reconnection: number;\n}\n\nexport type Internal = {\n bypassSerialBytesConnection: boolean;\n auto_response: boolean;\n device_number: number;\n aux_port_connector: number;\n last_error: LastError;\n serial: SerialData;\n device: DeviceData;\n time: TimeResponse;\n timeout: Timeout;\n interval: InternalIntervals;\n};\n\ninterface CoreConstructorParams {\n filters?: SerialPortFilter[] | null;\n config_port?: SerialOptions;\n no_device?: number;\n device_listen_on_channel?: number | string;\n bypassSerialBytesConnection?: boolean;\n socket?: boolean;\n transformStream?: false | TransformStream;\n}\n\nconst defaultConfigPort: SerialOptions = {\n baudRate: 9600,\n dataBits: 8,\n stopBits: 1,\n parity: \"none\",\n bufferSize: 32768,\n flowControl: \"none\",\n};\n\ninterface CustomCode {\n code: string | Uint8Array | Array<string> | Array<number>;\n}\n\ninterface ICore {\n lastAction: string | null;\n\n set listenOnChannel(channel: string | number);\n\n set serialFilters(filters: SerialPortFilter[]);\n\n get serialFilters(): SerialPortFilter[];\n\n set serialConfigPort(config_port: SerialOptions);\n\n get serialConfigPort(): SerialOptions;\n\n get isConnected(): boolean;\n\n get isConnecting(): boolean;\n\n get isDisconnected(): boolean;\n\n get useRTSCTS(): boolean;\n\n set useRTSCTS(value: boolean);\n\n get deviceNumber(): number;\n\n get uuid(): string;\n\n get typeDevice(): string;\n\n get queue(): QueueData[];\n\n get timeoutBeforeResponseBytes(): number;\n\n set timeoutBeforeResponseBytes(value: number);\n\n get fixedBytesMessage(): number | null;\n\n set fixedBytesMessage(length: number | null);\n\n get responseDelimited(): boolean;\n\n set responseDelimited(value: boolean);\n\n get responsePrefixLimited(): boolean;\n\n set responsePrefixLimited(value: boolean);\n\n get responseSufixLimited(): boolean;\n\n set responseSufixLimited(value: boolean);\n\n get responseLimiter(): string | RegExp | null;\n\n set responseLimiter(limiter: string | RegExp | null);\n\n get bypassSerialBytesConnection(): boolean;\n\n set bypassSerialBytesConnection(value: boolean);\n\n timeout(bytes: string[], event: string): Promise<void>;\n\n disconnect(detail?: null): Promise<void>;\n\n connect(): Promise<boolean>;\n\n serialDisconnect(): Promise<void>;\n\n serialPortsSaved(ports: SerialPort[]): Promise<void>;\n\n serialErrors(error: unknown | Error | DOMException): void;\n\n serialConnect(): Promise<void>;\n\n serialForget(): Promise<boolean>;\n\n decToHex(dec: number | string): string;\n\n hexToDec(hex: string): number;\n\n hexMaker(val?: string, min?: number): string;\n\n add0x(bytes: string[]): string[];\n\n bytesToHex(bytes: string[]): string[];\n\n appendToQueue(arr: string[], action: string): Promise<void>;\n\n serialSetConnectionConstant(listen_on_port?: number): string | Uint8Array | string[] | number[] | null;\n\n serialMessage(code: string[]): void;\n\n serialCorruptMessage(data: Uint8Array | number[] | string[] | never | null | string | ArrayBuffer): void;\n\n clearSerialQueue(): void;\n\n sumHex(arr: string[]): string;\n\n softReload(): void;\n\n sendConnect(): Promise<void>;\n\n sendCustomCode(customCode: CustomCode): Promise<void>;\n\n stringToArrayHex(string: string): string[];\n\n stringToArrayBuffer(string: string, end: string): ArrayBufferLike;\n\n parseStringToBytes(string: string, end: string): string[];\n\n parseUint8ToHex(array: Uint8Array): string[];\n\n parseHexToUint8(array: string[]): Uint8Array;\n\n stringArrayToUint8Array(strings: string[]): Uint8Array;\n\n parseUint8ArrayToString(array: string[]): string;\n\n parseStringToTextEncoder(string: string, end: string): Uint8Array;\n\n hexToAscii(hex: string | number): string;\n\n asciiToHex(asciiString: string): string;\n\n getResponseAsArrayBuffer(): void;\n\n getResponseAsArrayHex(): void;\n\n getResponseAsUint8Array(): void;\n\n getResponseAsString(): void;\n}\n\nexport class Core extends Dispatcher implements ICore {\n protected __internal__: Internal = {\n bypassSerialBytesConnection: false,\n auto_response: false,\n device_number: 1,\n aux_port_connector: 0,\n last_error: {\n message: null,\n action: null,\n code: null,\n no_code: 0,\n },\n serial: {\n transformStream: false,\n socket: false,\n portInfo: {\n path: null,\n vendorId: null,\n productId: null,\n parser: {\n name: \"inter-byte-timeout\",\n interval: 50,\n },\n },\n aux_connecting: \"idle\",\n connecting: false,\n connected: false,\n port: null,\n last_action: null,\n response: {\n length: null,\n buffer: new Uint8Array([]),\n as: \"uint8\",\n replacer: /[\\n\\r]+/g,\n limiter: null,\n prefixLimiter: false,\n sufixLimiter: true,\n delimited: false,\n },\n reader: null,\n input_done: null,\n output_done: null,\n input_stream: null,\n output_stream: null,\n keep_reading: true,\n time_until_send_bytes: undefined,\n delay_first_connection: 200,\n bytes_connection: null,\n filters: [],\n config_port: defaultConfigPort,\n queue: [],\n running_queue: false,\n auto_response: null,\n free_timeout_ms: 50, // In previous versions 400 was used\n useRTSCTS: false, // Use RTS/CTS flow control\n },\n device: {\n type: \"unknown\",\n id: window.crypto.randomUUID(),\n listen_on_port: null,\n },\n time: {\n response_connection: 500,\n response_engines: 2e3,\n response_general: 2e3,\n },\n timeout: {\n until_response: 0,\n },\n interval: {\n reconnection: 0,\n },\n };\n\n #boundFinishConnecting: EventListenerOrEventListenerObject | null = null;\n\n constructor(\n {\n filters = null,\n config_port = defaultConfigPort,\n no_device = 1,\n device_listen_on_channel = 1,\n bypassSerialBytesConnection = false,\n socket = false,\n transformStream = false,\n }: CoreConstructorParams = {\n filters: null,\n config_port: defaultConfigPort,\n no_device: 1,\n device_listen_on_channel: 1,\n bypassSerialBytesConnection: false,\n socket: false,\n transformStream: false,\n },\n ) {\n super();\n\n if (!(\"serial\" in navigator)) {\n throw new Error(\"Web Serial not supported\");\n }\n\n if (filters) {\n this.serialFilters = filters;\n }\n\n if (config_port) {\n this.serialConfigPort = config_port;\n }\n\n if (bypassSerialBytesConnection) {\n this.__internal__.bypassSerialBytesConnection = bypassSerialBytesConnection;\n }\n\n if (no_device) {\n this.#serialSetBytesConnection(no_device);\n }\n\n if (device_listen_on_channel && [\"number\", \"string\"].includes(typeof device_listen_on_channel)) {\n this.listenOnChannel = device_listen_on_channel;\n }\n\n this.__internal__.serial.socket = socket;\n this.__internal__.serial.transformStream = transformStream;\n\n this.#registerDefaultListeners();\n this.#internalEvents();\n }\n\n set listenOnChannel(channel: string | number) {\n if (typeof channel === \"string\") {\n channel = parseInt(channel);\n }\n if (isNaN(channel) || channel < 1 || channel > 255) {\n throw new Error(\"Invalid port number\");\n }\n this.__internal__.device.listen_on_port = channel;\n if (this.__internal__.bypassSerialBytesConnection) return;\n this.__internal__.serial.bytes_connection = this.serialSetConnectionConstant(channel);\n }\n\n get lastAction(): string | null {\n return this.__internal__.serial.last_action;\n }\n\n get listenOnChannel(): number {\n return this.__internal__.device.listen_on_port ?? 1;\n }\n\n set serialFilters(filters: SerialPortFilter[]) {\n if (this.isConnected) throw new Error(\"Cannot change serial filters while connected\");\n this.__internal__.serial.filters = filters;\n }\n\n get serialFilters(): SerialPortFilter[] {\n return this.__internal__.serial.filters;\n }\n\n set serialConfigPort(config_port: SerialOptions) {\n if (this.isConnected) throw new Error(\"Cannot change serial filters while connected\");\n this.__internal__.serial.config_port = config_port;\n }\n\n get serialConfigPort(): SerialOptions {\n return this.__internal__.serial.config_port;\n }\n\n get useRTSCTS(): boolean {\n return this.__internal__.serial.useRTSCTS;\n }\n\n set useRTSCTS(value: boolean) {\n this.__internal__.serial.useRTSCTS = value;\n }\n\n get isConnected(): boolean {\n const prevConnected = this.__internal__.serial.connected;\n const connected = this.#checkIfPortIsOpen(this.__internal__.serial.port);\n if (prevConnected && !connected) {\n this.#disconnected({ error: \"Port is closed, not readable or writable.\" });\n }\n this.__internal__.serial.connected = connected;\n return this.__internal__.serial.connected;\n }\n\n get isConnecting(): boolean {\n return this.__internal__.serial.connecting;\n }\n\n get isDisconnected(): boolean {\n const prevConnected = this.__internal__.serial.connected;\n const connected = this.#checkIfPortIsOpen(this.__internal__.serial.port);\n if (!prevConnected && connected) {\n this.dispatch(\"serial:connected\");\n this.#connectingChange(false);\n Devices.$dispatchChange(this);\n }\n this.__internal__.serial.connected = connected;\n return !this.__internal__.serial.connected;\n }\n\n get deviceNumber(): number {\n return this.__internal__.device_number;\n }\n\n get uuid(): string {\n return this.__internal__.device.id;\n }\n\n get typeDevice(): string {\n return this.__internal__.device.type;\n }\n\n get queue(): QueueData[] {\n return this.__internal__.serial.queue;\n }\n\n get responseDelimited(): boolean {\n return this.__internal__.serial.response.delimited;\n }\n\n set responseDelimited(value: boolean) {\n if (typeof value !== \"boolean\") {\n throw new Error(\"responseDelimited must be a boolean\");\n }\n this.__internal__.serial.response.delimited = value;\n }\n\n get responsePrefixLimited(): boolean {\n return this.__internal__.serial.response.prefixLimiter;\n }\n\n set responsePrefixLimited(value: boolean) {\n if (typeof value !== \"boolean\") {\n throw new Error(\"responsePrefixLimited must be a boolean\");\n }\n this.__internal__.serial.response.prefixLimiter = value;\n }\n\n get responseSufixLimited(): boolean {\n return this.__internal__.serial.response.sufixLimiter;\n }\n\n set responseSufixLimited(value: boolean) {\n if (typeof value !== \"boolean\") {\n throw new Error(\"responseSufixLimited must be a boolean\");\n }\n this.__internal__.serial.response.sufixLimiter = value;\n }\n\n get responseLimiter(): string | RegExp | null {\n return this.__internal__.serial.response.limiter;\n }\n\n set responseLimiter(limiter: string | RegExp | null) {\n if (typeof limiter !== \"string\" && !(limiter instanceof RegExp)) {\n throw new Error(\"responseLimiter must be a string or a RegExp\");\n }\n\n this.__internal__.serial.response.limiter = limiter;\n }\n\n get fixedBytesMessage(): number | null {\n return this.__internal__.serial.response.length;\n }\n\n set fixedBytesMessage(length: number | null) {\n if (length !== null && (typeof length !== \"number\" || length < 1)) {\n throw new Error(\"Invalid length for fixed bytes message\");\n }\n this.__internal__.serial.response.length = length;\n }\n\n get timeoutBeforeResponseBytes(): number {\n return this.__internal__.serial.free_timeout_ms || 50;\n }\n\n set timeoutBeforeResponseBytes(value: number) {\n if (value !== undefined && (typeof value !== \"number\" || value < 1)) {\n throw new Error(\"Invalid timeout for response bytes\");\n }\n this.__internal__.serial.free_timeout_ms = value ?? 50;\n }\n\n get bypassSerialBytesConnection(): boolean {\n return this.__internal__.bypassSerialBytesConnection;\n }\n\n set bypassSerialBytesConnection(value: boolean) {\n if (typeof value !== \"boolean\") {\n throw new Error(\"bypassSerialBytesConnection must be a boolean\");\n }\n this.__internal__.bypassSerialBytesConnection = value;\n }\n\n get useSocket(): boolean {\n return this.__internal__.serial.socket;\n }\n\n get connectionBytes(): Uint8Array {\n const bytes = this.__internal__.serial.bytes_connection;\n\n if (bytes instanceof Uint8Array) {\n return bytes;\n }\n\n if (typeof bytes === \"string\") {\n return this.stringArrayToUint8Array(this.parseStringToBytes(bytes, \"\"));\n }\n\n if (Array.isArray(bytes) && typeof bytes[0] === \"string\") {\n return this.stringArrayToUint8Array(bytes as string[]);\n }\n\n if (Array.isArray(bytes) && typeof bytes[0] === \"number\") {\n return new Uint8Array(bytes as number[]);\n }\n\n return new Uint8Array([]);\n }\n\n set portPath(path: string | null) {\n if (this.isConnected) throw new Error(\"Cannot change port path while connected\");\n if (typeof path !== \"string\" && path !== null) {\n throw new TypeError(\"vendorId must be string or null\");\n }\n this.__internal__.serial.portInfo.path = path;\n }\n\n get portPath(): string | null {\n return this.__internal__.serial.portInfo.path;\n }\n\n set portVendorId(vendorId: number | string | null) {\n if (this.isConnected) throw new Error(\"Cannot change port vendorId while connected\");\n if (typeof vendorId! == \"number\" && typeof vendorId !== \"string\" && vendorId !== null) {\n throw new TypeError(\"vendorId must be a number, string or null\");\n }\n this.__internal__.serial.portInfo.vendorId = vendorId;\n }\n\n get portVendorId(): number | string | null {\n return this.__internal__.serial.portInfo.vendorId;\n }\n\n set portProductId(productId: number | string | null) {\n if (this.isConnected) throw new Error(\"Cannot change port productId while connected\");\n if (typeof productId! == \"number\" && typeof productId !== \"string\" && productId !== null) {\n throw new TypeError(\"productId must be a number, string or null\");\n }\n this.__internal__.serial.portInfo.productId = productId;\n }\n\n get portProductId(): number | string | null {\n return this.__internal__.serial.portInfo.productId;\n }\n\n set socketPortParser(string: \"byte-length\" | \"inter-byte-timeout\") {\n if ([\"byte-length\", \"inter-byte-timeout\"].includes(string)) {\n throw new TypeError(\"socketPortParser must be a string, either 'byte-length' or 'inter-byte-timeout'\");\n }\n this.__internal__.serial.portInfo.parser.name = string;\n }\n\n get socketPortParser(): \"byte-length\" | \"inter-byte-timeout\" {\n return this.__internal__.serial.portInfo.parser.name;\n }\n\n set socketPortParserInterval(value: number) {\n if (typeof value !== \"number\" || value < 1) {\n throw new TypeError(\"Interval must be a positive number\");\n }\n\n this.__internal__.serial.portInfo.parser.interval = value;\n }\n\n get socketPortParserInterval(): number {\n return this.__internal__.serial.portInfo.parser.interval || 50;\n }\n\n set socketPortParserLength(value: number) {\n if (typeof value !== \"number\" || value < 1) {\n throw new TypeError(\"Length must be a positive number or null\");\n }\n this.__internal__.serial.portInfo.parser.length = value;\n }\n\n get socketPortParserLength(): number {\n return this.__internal__.serial.portInfo.parser.length || 14;\n }\n\n get parserForSocket() {\n if (this.socketPortParser === \"byte-length\") {\n return {\n name: this.socketPortParser,\n length: this.socketPortParserLength,\n };\n }\n return {\n name: this.socketPortParser,\n interval: this.socketPortParserInterval,\n };\n }\n\n get configDeviceSocket(): object {\n return {\n uuid: this.uuid,\n name: this.typeDevice,\n deviceNumber: this.deviceNumber,\n connectionBytes: Array.from(this.connectionBytes),\n config: {\n baudRate: this.__internal__.serial.config_port.baudRate,\n dataBits: this.__internal__.serial.config_port.dataBits,\n stopBits: this.__internal__.serial.config_port.stopBits,\n parity: this.__internal__.serial.config_port.parity,\n bufferSize: this.__internal__.serial.config_port.bufferSize,\n flowControl: this.__internal__.serial.config_port.flowControl,\n },\n info: {\n vendorId: this.portVendorId, // vendor ID or null for auto-detect\n productId: this.portProductId, // product ID or null for auto-detect\n portName: this.portPath, // COM3, /dev/ttyUSB0, etc. null for auto-detect\n },\n response: {\n automatic: this.__internal__.auto_response, // true to auto-respond to commands this only for devices that doesn't respond nothing\n autoResponse: this.__internal__.serial.auto_response, // null or data to respond automatically, ie. [0x02, 0x06, 0xdd, 0xdd, 0xf0, 0xcf, 0x03] for relay\n parser: this.parserForSocket,\n timeout: {\n general: this.__internal__.time.response_general,\n engines: this.__internal__.time.response_engines,\n connection: this.__internal__.time.response_connection,\n },\n },\n };\n }\n\n #checkIfPortIsOpen(port: SerialPort | null): boolean {\n if (this.useSocket) {\n return this.__internal__.serial.connected && Socket.isConnected();\n }\n\n return !!(port && port.readable && port.writable);\n }\n\n public async timeout(bytes: string | Uint8Array | Array<string> | Array<number>, event: string): Promise<void> {\n this.__internal__.last_error.message = \"Operation response timed out.\";\n this.__internal__.last_error.action = event;\n this.__internal__.last_error.code = bytes;\n if (this.__internal__.timeout.until_response) {\n clearTimeout(this.__internal__.timeout.until_response);\n this.__internal__.timeout.until_response = 0;\n }\n if (event === \"connect\") {\n this.__internal__.serial.connected = false;\n this.dispatch(\"serial:reconnect\", {});\n Devices.$dispatchChange(this);\n } else if (event === \"connection:start\") {\n await this.serialDisconnect();\n this.__internal__.serial.connected = false;\n this.__internal__.aux_port_connector += 1;\n Devices.$dispatchChange(this);\n await this.serialConnect();\n }\n\n if (this.__internal__.serial.queue.length > 0) {\n this.dispatch(\"internal:queue\", {});\n }\n\n this.dispatch(\"serial:timeout\", {\n ...this.__internal__.last_error,\n bytes,\n action: event,\n });\n }\n\n public async disconnect(detail = null): Promise<void> {\n await this.serialDisconnect();\n this.#disconnected(detail);\n }\n\n #disconnected(detail: object | null = null): void {\n this.__internal__.serial.connected = false;\n this.__internal__.aux_port_connector = 0;\n this.dispatch(\"serial:disconnected\", detail);\n Devices.$dispatchChange(this);\n }\n\n #onFinishConnecting(event: any): void {\n this.__internal__.serial.aux_connecting = event.detail.active ? \"connecting\" : \"finished\";\n }\n\n socketResponse(data: any) {\n const auxPrevConnected: boolean = this.__internal__.serial.connected;\n\n if (data.type === \"disconnect\" || (data.type === \"error\" && data.data === \"DISCONNECTED\")) {\n this.__internal__.serial.connected = false;\n } else if (data.type === \"success\") {\n this.__internal__.serial.connected = true;\n }\n\n Devices.$dispatchChange(this);\n if (!auxPrevConnected && this.__internal__.serial.connected) {\n this.dispatch(\"serial:connected\");\n this.#connectingChange(false);\n }\n\n // console.log(data, this.lastAction);\n if (data.type === \"success\") {\n this.#serialGetResponse(new Uint8Array(data.data));\n } else if (data.type === \"error\") {\n const error = new Error(\"The port is closed or is not readable/writable\");\n this.serialErrors(error);\n } else if (data.type === \"timeout\") {\n this.timeout(data.data.bytes ?? [], this.lastAction || \"unknown\");\n }\n\n this.__internal__.serial.last_action = null;\n }\n\n public async connect(): Promise<boolean> {\n if (this.isConnected) {\n return true;\n }\n\n this.__internal__.serial.aux_connecting = \"idle\";\n\n return new Promise((resolve: (value: boolean) => void, reject: (reason: string) => void): void => {\n if (!this.#boundFinishConnecting) {\n this.#boundFinishConnecting = this.#onFinishConnecting.bind(this);\n }\n\n this.on(\"internal:connecting\", this.#boundFinishConnecting);\n\n const interval: ReturnType<typeof setInterval> = setInterval((): void => {\n if (this.__internal__.serial.aux_connecting === \"finished\") {\n clearInterval(interval);\n this.__internal__.serial.aux_connecting = \"idle\";\n if (null !== this.#boundFinishConnecting) {\n this.off(\"internal:connecting\", this.#boundFinishConnecting);\n }\n\n if (this.isConnected) {\n resolve(true);\n } else {\n reject(`${this.typeDevice} device ${this.deviceNumber} not connected`);\n }\n } else if (this.__internal__.serial.aux_connecting === \"connecting\") {\n this.__internal__.serial.aux_connecting = \"idle\";\n this.dispatch(\"internal:connecting\", { active: true });\n this.dispatch(\"serial:connecting\", { active: true });\n }\n }, 100);\n\n this.serialConnect();\n });\n }\n\n public async serialDisconnect(): Promise<void> {\n try {\n if (this.useSocket) {\n if (Socket.isConnected()) {\n Socket.disconnectDevice(this.configDeviceSocket);\n }\n } else {\n const reader: ReadableStreamDefaultReader<Uint8Array> | null = this.__internal__.serial.reader;\n const output_stream: WritableStream<Uint8Array> | null = this.__internal__.serial.output_stream;\n if (reader) {\n const reader_promise: Promise<void> = reader.cancel();\n await reader_promise.catch((err: unknown): void => this.serialErrors(err));\n await this.__internal__.serial.input_done;\n }\n\n if (output_stream) {\n await output_stream.getWriter().close();\n await this.__internal__.serial.output_done;\n }\n\n if (this.__internal__.serial.connected && this.__internal__.serial && this.__internal__.serial.port) {\n await this.__internal__.serial.port.close();\n }\n }\n } catch (err: unknown) {\n this.serialErrors(err);\n } finally {\n this.__internal__.serial.reader = null;\n this.__internal__.serial.input_done = null;\n\n this.__internal__.serial.output_stream = null;\n this.__internal__.serial.output_done = null;\n\n this.__internal__.serial.connected = false;\n this.__internal__.serial.port = null;\n Devices.$dispatchChange(this);\n }\n }\n\n async #serialSocketWrite(data: string | Uint8Array | Array<string> | Array<number>): Promise<void> {\n if (Socket.isDisconnected()) {\n this.#disconnected({ error: \"Socket is disconnected.\" });\n throw new Error(\"The socket is disconnected\");\n }\n\n if (this.isDisconnected) {\n this.#disconnected({ error: \"Port is closed, not readable or writable.\" });\n throw new Error(\"The port is closed or is not readable/writable\");\n }\n\n const bytes: Uint8Array = this.validateBytes(data);\n Socket.write({ config: this.configDeviceSocket, bytes: Array.from(bytes) });\n }\n\n async #serialWrite(data: string | Uint8Array | Array<string> | Array<number>): Promise<void> {\n if (this.useSocket) {\n await this.#serialSocketWrite(data);\n return;\n }\n const port: SerialPort | null = this.__internal__.serial.port;\n if (!port || (port && (!port.readable || !port.writable))) {\n this.#disconnected({ error: \"Port is closed, not readable or writable.\" });\n throw new Error(\"The port is closed or is not readable/writable\");\n }\n const bytes: Uint8Array = this.validateBytes(data);\n\n if (this.useRTSCTS) {\n await this.#waitForCTS(port, 5000);\n }\n\n if (port.writable === null) return; // never happens, it's already checked, but to suppress TS error\n const writer: WritableStreamDefaultWriter<Uint8Array> = port.writable.getWriter();\n await writer.write(bytes);\n writer.releaseLock();\n }\n\n async #waitForCTS(port: SerialPort, timeoutMs: number = 5000): Promise<void> {\n const start = Date.now();\n while (true) {\n if (Date.now() - start > timeoutMs) {\n throw new Error(\"Timeout waiting for clearToSend signal\");\n }\n\n const { clearToSend } = await port.getSignals();\n if (clearToSend) return;\n await wait(100);\n }\n }\n\n #serialGetResponse(code: Uint8Array = new Uint8Array([]), corrupt: boolean = false) {\n if (code && code.length > 0) {\n const auxPrevConnected: boolean = this.__internal__.serial.connected;\n this.__internal__.serial.connected = this.#checkIfPortIsOpen(this.__internal__.serial.port);\n Devices.$dispatchChange(this);\n if (!auxPrevConnected && this.__internal__.serial.connected) {\n this.dispatch(\"serial:connected\");\n this.#connectingChange(false);\n }\n\n if (this.__internal__.interval.reconnection) {\n clearInterval(this.__internal__.interval.reconnection);\n this.__internal__.interval.reconnection = 0;\n }\n\n if (this.__internal__.timeout.until_response) {\n clearTimeout(this.__internal__.timeout.until_response);\n this.__internal__.timeout.until_response = 0;\n }\n\n if (this.__internal__.serial.response.as === \"hex\") {\n if (corrupt) {\n this.serialCorruptMessage(this.parseUint8ToHex(code));\n } else {\n this.serialMessage(this.parseUint8ToHex(code));\n }\n } else if (this.__internal__.serial.response.as === \"uint8\") {\n if (corrupt) {\n this.serialCorruptMessage(code);\n } else {\n this.serialMessage(code);\n }\n } else if (this.__internal__.serial.response.as === \"string\") {\n const str = this.parseUint8ArrayToString(code);\n if (this.__internal__.serial.response.limiter !== null) {\n const splited = str.split(this.__internal__.serial.response.limiter);\n for (const s in splited) {\n if (!splited[s]) continue;\n if (corrupt) {\n this.serialCorruptMessage(splited[s]);\n } else {\n this.serialMessage(splited[s]);\n }\n }\n } else {\n if (corrupt) {\n this.serialCorruptMessage(str);\n } else {\n this.serialMessage(str);\n }\n }\n } else {\n const arraybuffer: ArrayBuffer | ArrayBufferLike = this.stringToArrayBuffer(this.parseUint8ArrayToString(code));\n if (corrupt) {\n this.serialCorruptMessage(arraybuffer as ArrayBuffer);\n } else {\n this.serialMessage(arraybuffer as ArrayBuffer);\n }\n }\n }\n\n if (this.__internal__.serial.queue.length === 0) {\n this.__internal__.serial.running_queue = false;\n return;\n }\n this.dispatch(\"internal:queue\", {});\n }\n\n public getResponseAsArrayBuffer(): void {\n this.__internal__.serial.response.as = \"arraybuffer\";\n }\n\n public getResponseAsArrayHex(): void {\n this.__internal__.serial.response.as = \"hex\";\n }\n\n public getResponseAsUint8Array(): void {\n this.__internal__.serial.response.as = \"uint8\";\n }\n\n public getResponseAsString(): void {\n this.__internal__.serial.response.as = \"string\";\n }\n\n async #serialPortsFiltered(): Promise<SerialPort[]> {\n const filters: SerialPortFilter[] = this.serialFilters;\n // @ts-expect-error getPorts can use parameters\n const ports: SerialPort[] = await navigator.serial.getPorts({ filters });\n if (filters.length === 0) return ports;\n\n const filteredPorts: SerialPort[] = ports.filter((port: SerialPort): boolean => {\n const info: SerialPortInfo = port.getInfo();\n return filters.some((filter: SerialPortFilter): boolean => {\n return info.usbProductId === filter.usbProductId && info.usbVendorId === filter.usbVendorId;\n });\n });\n\n // return only ports that are not open\n return filteredPorts.filter((port: SerialPort): boolean => !this.#checkIfPortIsOpen(port));\n }\n\n public async serialPortsSaved(ports: SerialPort[]): Promise<void> {\n const filters: SerialPortFilter[] = this.serialFilters;\n if (this.__internal__.aux_port_connector < ports.length) {\n const aux = this.__internal__.aux_port_connector;\n this.__internal__.serial.port = ports[aux];\n } else {\n this.__internal__.aux_port_connector = 0;\n this.__internal__.serial.port = await navigator.serial.requestPort({\n filters,\n });\n }\n if (!this.__internal__.serial.port) {\n throw new Error(\"Select another port please\");\n }\n }\n\n public serialErrors(error: any): void {\n const err = error.toString().toLowerCase();\n switch (true) {\n case err.includes(\"must be handling a user gesture to show a permission request\"):\n case err.includes(\"the port is closed.\"):\n case err.includes(\"the port is closed or is not writable\"):\n case err.includes(\"the port is closed or is not readable\"):\n case err.includes(\"the port is closed or is not readable/writable\"):\n case err.includes(\"select another port please\"):\n case err.includes(\"no port selected by the user\"):\n case err.includes(\n \"this readable stream reader has been released and cannot be used to cancel its previous owner stream\",\n ):\n this.dispatch(\"serial:need-permission\", {});\n Devices.$dispatchChange(this);\n break;\n case err.includes(\"the port is already open.\"):\n case err.includes(\"failed to open serial port\"):\n this.serialDisconnect().then(async () => {\n this.__internal__.aux_port_connector += 1;\n await this.serialConnect();\n });\n break;\n case err.includes(\"cannot read properties of undefined (reading 'writable')\"):\n case err.includes(\"cannot read properties of null (reading 'writable')\"):\n case err.includes(\"cannot read property 'writable' of null\"):\n case err.includes(\"cannot read property 'writable' of undefined\"):\n this.serialDisconnect().then(async () => {\n await this.serialConnect();\n });\n break;\n case err.includes(\"'close' on 'serialport': a call to close() is already in progress.\"):\n // ... do something?\n break;\n case err.includes(\"failed to execute 'open' on 'serialport': a call to open() is already in progress.\"):\n // ... do something?\n break;\n case err.includes(\"the port is already closed.\"):\n // ... do something?\n break;\n case err.includes(\"the device has been lost\"):\n this.dispatch(\"serial:lost\", {});\n Devices.$dispatchChange(this);\n // dispatch event\n break;\n case err.includes(\"navigator.serial is undefined\"):\n this.dispatch(\"serial:unsupported\", {});\n // dispatch event\n break;\n default:\n // unhandled error\n console.error(error);\n break;\n }\n\n this.dispatch(\"serial:error\", error);\n }\n\n #appendBuffer(arraybuffer: Uint8Array | ArrayBuffer | null): void {\n if (arraybuffer) {\n const incoming: Uint8Array = this.__internal__.serial.response.buffer;\n const tmp: Uint8Array = new Uint8Array(incoming.length + arraybuffer.byteLength);\n tmp.set(incoming, 0);\n tmp.set(new Uint8Array(arraybuffer), incoming.length);\n this.__internal__.serial.response.buffer = tmp;\n }\n }\n\n async #transformStreamLoop(): Promise<void> {\n if (this.__internal__.serial.time_until_send_bytes) {\n clearTimeout(this.__internal__.serial.time_until_send_bytes);\n this.__internal__.serial.time_until_send_bytes = 0;\n }\n\n if (this.__internal__.serial.response.buffer) {\n this.#serialGetResponse(this.__internal__.serial.response.buffer);\n }\n this.__internal__.serial.response.buffer = new Uint8Array(0);\n }\n\n async #freeSerialLoop(): Promise<void> {\n if (this.__internal__.serial.time_until_send_bytes) {\n clearTimeout(this.__internal__.serial.time_until_send_bytes);\n this.__internal__.serial.time_until_send_bytes = 0;\n }\n\n this.__internal__.serial.time_until_send_bytes = setTimeout((): void => {\n if (this.__internal__.serial.response.buffer) {\n this.#serialGetResponse(this.__internal__.serial.response.buffer);\n }\n\n this.__internal__.serial.response.buffer = new Uint8Array(0);\n }, this.__internal__.serial.free_timeout_ms || 50);\n }\n\n async #slicedSerialLoop(): Promise<void> {\n const expectedLength = this.__internal__.serial.response.length;\n let buffer = this.__internal__.serial.response.buffer;\n\n if (this.__internal__.serial.time_until_send_bytes) {\n clearTimeout(this.__internal__.serial.time_until_send_bytes);\n this.__internal__.serial.time_until_send_bytes = 0;\n }\n\n if (expectedLength === null || !buffer || buffer.length === 0) return;\n\n while (buffer.length >= expectedLength) {\n const message = buffer.slice(0, expectedLength);\n this.#serialGetResponse(message);\n\n buffer = buffer.slice(expectedLength);\n }\n this.__internal__.serial.response.buffer = buffer;\n\n if (buffer.length > 0) {\n this.__internal__.serial.time_until_send_bytes = setTimeout((): void => {\n this.#serialGetResponse(this.__internal__.serial.response.buffer, true);\n }, this.__internal__.serial.free_timeout_ms || 50);\n }\n }\n\n async #delimitedSerialLoop(): Promise<void> {\n const {\n limiter,\n prefixLimiter = false,\n sufixLimiter = true,\n }: {\n limiter: string | RegExp | null;\n prefixLimiter?: boolean;\n sufixLimiter?: boolean;\n } = this.__internal__.serial.response;\n\n if (!limiter) {\n throw new Error(\"No limiter defined for delimited serial response\");\n }\n\n const buffer = this.__internal__.serial.response.buffer;\n\n if (!limiter || !buffer || buffer.length === 0) return;\n\n if (this.__internal__.serial.time_until_send_bytes) {\n clearTimeout(this.__internal__.serial.time_until_send_bytes);\n this.__internal__.serial.time_until_send_bytes = 0;\n }\n\n const decoder = new TextDecoder();\n let decoded = decoder.decode(buffer);\n const messages: Uint8Array[] = [];\n\n if (typeof limiter === \"string\") {\n let pattern: RegExp;\n if (prefixLimiter && sufixLimiter) {\n pattern = new RegExp(`${limiter}([^${limiter}]+)${limiter}`, \"g\");\n } else if (prefixLimiter) {\n pattern = new RegExp(`${limiter}([^${limiter}]*)`, \"g\");\n } else if (sufixLimiter) {\n pattern = new RegExp(`([^${limiter}]+)${limiter}`, \"g\");\n } else {\n return;\n }\n\n let match;\n let lastIndex = 0;\n while ((match = pattern.exec(decoded)) !== null) {\n messages.push(new TextEncoder().encode(match[1]));\n lastIndex = pattern.lastIndex;\n }\n\n decoded = decoded.slice(lastIndex);\n } else if (limiter instanceof RegExp) {\n let match;\n let lastIndex = 0;\n if (prefixLimiter && sufixLimiter) {\n const pattern = new RegExp(`${limiter.source}(.*?)${limiter.source}`, \"g\");\n while ((match = pattern.exec(decoded)) !== null) {\n messages.push(new TextEncoder().encode(match[1]));\n lastIndex = pattern.lastIndex;\n }\n } else if (sufixLimiter) {\n while ((match = limiter.exec(decoded)) !== null) {\n const end = match.index;\n const chunk = decoded.slice(lastIndex, end);\n messages.push(new TextEncoder().encode(chunk));\n lastIndex = limiter.lastIndex;\n }\n } else if (prefixLimiter) {\n const parts = decoded.split(limiter);\n parts.shift();\n for (const part of parts) {\n messages.push(new TextEncoder().encode(part));\n }\n decoded = \"\";\n }\n\n decoded = decoded.slice(lastIndex);\n }\n\n for (const msg of messages) {\n this.#serialGetResponse(msg);\n }\n\n const leftoverBytes = new TextEncoder().encode(decoded);\n this.__internal__.serial.response.buffer = leftoverBytes;\n\n if (leftoverBytes.length > 0) {\n this.__internal__.serial.time_until_send_bytes = setTimeout((): void => {\n this.#serialGetResponse(this.__internal__.serial.response.buffer, true);\n this.__internal__.serial.response.buffer = new Uint8Array(0);\n }, this.__internal__.serial.free_timeout_ms ?? 50);\n }\n }\n\n async #readSerialLoop(): Promise<void> {\n const port: SerialPort | null = this.__internal__.serial.port;\n if (!port || !port.readable) throw new Error(\"Port is not readable\");\n\n const parser = this.__internal__.serial.transformStream ? this.__internal__.serial.transformStream : null;\n const reader: ReadableStreamDefaultReader<Uint8Array> = parser\n ? port.readable.pipeThrough(parser).getReader()\n : port.readable.getReader();\n //const reader: ReadableStreamDefaultReader<Uint8Array> = port.readable.getReader();\n\n this.__internal__.serial.reader = reader;\n\n try {\n while (this.__internal__.serial.keep_reading) {\n const { value, done } = await reader.read();\n if (done) break;\n\n this.#appendBuffer(value);\n\n if (this.__internal__.serial.transformStream) {\n await this.#transformStreamLoop();\n } else if (this.__internal__.serial.response.delimited) {\n await this.#delimitedSerialLoop();\n } else if (this.__internal__.serial.response.length === null) {\n await this.#freeSerialLoop();\n } else {\n await this.#slicedSerialLoop();\n }\n }\n } catch (err: unknown) {\n this.serialErrors(err);\n } finally {\n reader.releaseLock();\n this.__internal__.serial.keep_reading = true;\n\n if (this.__internal__.serial.port) {\n await this.__internal__.serial.port.close();\n }\n }\n }\n\n #connectingChange(value: boolean): void {\n if (value === this.__internal__.serial.connecting) return;\n\n this.__internal__.serial.connecting = value;\n this.dispatch(\"serial:connecting\", { active: value });\n this.dispatch(\"internal:connecting\", { active: value });\n }\n\n public async serialConnect(): Promise<void> {\n try {\n this.#connectingChange(true);\n\n if (this.useSocket) {\n Socket.prepare();\n this.__internal__.serial.last_action = \"connect\";\n this.__internal__.timeout.until_response = setTimeout(async (): Promise<void> => {\n await this.timeout(this.__internal__.serial.bytes_connection ?? [], \"connection:start\");\n }, this.__internal__.time.response_connection);\n if (Socket.isDisconnected()) {\n return;\n }\n Socket.connectDevice(this.configDeviceSocket);\n this.dispatch(\"serial:sent\", {\n action: \"connect\",\n bytes: this.__internal__.serial.bytes_connection,\n });\n } else {\n const ports: SerialPort[] = await this.#serialPortsFiltered();\n if (ports.length > 0) {\n await this.serialPortsSaved(ports);\n } else {\n const filters: SerialPortFilter[] = this.serialFilters;\n this.__internal__.serial.port = await navigator.serial.requestPort({\n filters,\n });\n }\n\n const port: SerialPort | null = this.__internal__.serial.port;\n if (!port) {\n throw new Error(\"No port selected by the user\");\n }\n await port.open(this.serialConfigPort);\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const this1: this = this;\n port.onconnect = (event: Event): void => {\n // console.log(event);\n this1.dispatch(\"serial:connected\", event);\n this1.#connectingChange(false);\n Devices.$dispatchChange(this);\n if (this1.__internal__.serial.queue.length > 0) {\n this1.dispatch(\"internal:queue\", {});\n } else {\n this1.__internal__.serial.running_queue = false;\n }\n };\n port.ondisconnect = async (): Promise<void> => {\n await this1.disconnect();\n };\n\n await wait(this.__internal__.serial.delay_first_connection);\n\n this.__internal__.timeout.until_response = setTimeout(async (): Promise<void> => {\n await this1.timeout(this1.__internal__.serial.bytes_connection ?? [], \"connection:start\");\n }, this.__internal__.time.response_connection);\n\n this.__internal__.serial.last_action = \"connect\";\n await this.#serialWrite(this.__internal__.serial.bytes_connection ?? []);\n\n this.dispatch(\"serial:sent\", {\n action: \"connect\",\n bytes: this.__internal__.serial.bytes_connection,\n });\n\n if (this.__internal__.auto_response) {\n this.#serialGetResponse(this.__internal__.serial.auto_response);\n }\n await this.#readSerialLoop();\n }\n } catch (e: unknown) {\n this.#connectingChange(false);\n this.serialErrors(e);\n }\n }\n\n async #forget(): Promise<boolean> {\n if (typeof window === \"undefined\") return false;\n\n if (\"serial\" in navigator && \"forget\" in SerialPort.prototype && this.__internal__.serial.port) {\n await this.__internal__.serial.port.forget();\n return true;\n }\n return false;\n }\n\n public async serialForget(): Promise<boolean> {\n return await this.#forget();\n }\n\n public decToHex(dec: number | string): string {\n if (typeof dec === \"string\") {\n dec = parseInt(dec, 10);\n }\n return dec.toString(16);\n }\n\n public hexToDec(hex: string): number {\n return parseInt(hex, 16);\n }\n\n public hexMaker(val = \"00\", min = 2): string {\n return val.toString().padStart(min, \"0\").toLowerCase();\n }\n\n public add0x(bytes: string[]): string[] {\n const new_bytes: string[] = [];\n bytes.forEach((value: string, index: number): void => {\n new_bytes[index] = \"0x\" + value;\n });\n return new_bytes;\n }\n\n public bytesToHex(bytes: string[]): string[] {\n return this.add0x(Array.from(bytes, (byte: string): string => this.hexMaker(byte)));\n }\n\n #registerDefaultListeners(): void {\n const availableListeners: string[] = [\n \"serial:connected\",\n \"serial:connecting\",\n \"serial:reconnect\",\n \"serial:timeout\",\n \"serial:disconnected\",\n \"serial:sent\",\n \"serial:soft-reload\",\n \"serial:message\",\n \"serial:corrupt-message\",\n \"unknown\",\n \"serial:need-permission\",\n \"serial:lost\",\n \"serial:unsupported\",\n \"serial:error\",\n \"debug\",\n ];\n\n availableListeners.forEach((event: string): void => {\n this.serialRegisterAvailableListener(event);\n });\n }\n\n #internalEvents(): void {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const this1: this = this;\n this.on(\"internal:queue\", async (): Promise<void> => {\n await this1.#runQueue();\n });\n\n const onSerialSocketDisconnect = (): void => {\n if (this1.isConnected) {\n this1.#disconnected({ error: \"Socket disconnected.\" });\n }\n };\n const onSerialSocketConnect = (): void => {\n if (this1.isDisconnected && !this1.isConnecting) {\n this1.serialConnect().catch((): void => {});\n }\n };\n if (this.useSocket) {\n window.addEventListener(\"serial:socket:disconnected\", onSerialSocketDisconnect);\n window.addEventListener(\"serial:socket:connected\", onSerialSocketConnect);\n }\n\n this.#browserEvents();\n }\n\n #browserEvents(): void {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const this1: this = this;\n navigator.serial.addEventListener(\"connect\", async (): Promise<void> => {\n if (!this1.isDisconnected) return;\n await this1.serialConnect().catch((): void => {});\n });\n }\n\n async #runQueue(): Promise<void> {\n if (this.useSocket && Socket.isDisconnected()) {\n // socket disconnected, by default socket.io will try to reconnect\n // just wait for reconnection, until then, do not process the queue\n // but keep stop the queue processing, will start when socket reconnects and\n // properly emits the 'serial:socket:connected' event to connect again the device\n // then the queue will be processed again\n return;\n }\n if (!this.#checkIfPortIsOpen(this.__internal__.serial.port)) {\n this.#disconnected({ error: \"Port is closed, not readable or writable.\" });\n await this.serialConnect();\n return;\n }\n\n // check if something is waiting for a response, when response arrives, the queue will be processed\n if (this.__internal__.timeout.until_response) return;\n\n if (this.__internal__.serial.queue.length === 0) {\n this.__internal__.serial.running_queue = false;\n return;\n }\n this.__internal__.serial.running_queue = true;\n\n // first element in queue\n const first: QueueData = this.__internal__.serial.queue[0];\n let limit_response: number = this.__internal__.time.response_general;\n if (first.action === \"connect\") {\n limit_response = this.__internal__.time.response_connection;\n }\n\n this.__internal__.timeout.until_response = setTimeout(async (): Promise<void> => {\n await this.timeout(first.bytes, first.action);\n }, limit_response);\n\n this.__internal__.serial.last_action = first.action ?? \"unknown\";\n await this.#serialWrite(first.bytes);\n\n this.dispatch(\"serial:sent\", {\n action: first.action,\n bytes: first.bytes,\n });\n\n if (this.__internal__.auto_response) {\n let bytes: Uint8Array = new Uint8Array(0);\n try {\n bytes = this.validateBytes(this.__internal__.serial.auto_response);\n } catch (e: unknown) {\n this.serialErrors(e);\n }\n\n this.#serialGetResponse(bytes);\n }\n const copy_queue: QueueData[] = [...this.__internal__.serial.queue];\n this.__internal__.serial.queue = copy_queue.splice(1);\n\n if (this.__internal__.serial.queue.length > 0) {\n this.__internal__.serial.running_queue = true;\n //this.dispatch(\"internal:queue\", {});\n }\n }\n\n public validateBytes(data: string | Uint8Array | Array<string> | Array<number>): Uint8Array {\n let bytes: Uint8Array = new Uint8Array(0);\n if (data instanceof Uint8Array) {\n bytes = data;\n } else if (typeof data === \"string\") {\n bytes = this.parseStringToTextEncoder(data);\n } else if (Array.isArray(data) && typeof data[0] === \"string\") {\n bytes = this.stringArrayToUint8Array(data as string[]);\n } else if (Array.isArray(data) && typeof data[0] === \"number\") {\n bytes = new Uint8Array(data as unknown as number[]);\n } else {\n throw new Error(\"Invalid data type\");\n }\n return bytes;\n }\n\n public async appendToQueue(arr: string | Uint8Array | string[] | number[], action: string): Promise<void> {\n const bytes: Uint8Array = this.validateBytes(arr);\n\n if ([\"connect\", \"connection:start\"].includes(action)) {\n if (this.__internal__.serial.connected) return;\n\n // ignore queue because the connection is not established, so first message is connection\n // queue will never send a message before connection is established\n\n await this.serialConnect();\n return;\n }\n\n this.__internal__.serial.queue.push({ bytes, action });\n this.dispatch(\"internal:queue\", {});\n }\n\n #serialSetBytesConnection(no_device = 1): void {\n this.__internal__.device_number = no_device;\n if (this.__internal__.bypassSerialBytesConnection) return;\n this.__internal__.serial.bytes_connection = this.serialSetConnectionConstant(no_device);\n }\n\n public serialSetConnectionConstant(listen_on_port = 1): string | Uint8Array | string[] | number[] | null {\n if (this.__internal__.bypassSerialBytesConnection) return this.__internal__.serial.bytes_connection;\n\n // console.warn(\"wtf?\", this.bypassSerialBytesConnection);\n\n throw new Error(`Method not implemented 'serialSetConnectionConstant' to listen on channel ${listen_on_port}`);\n // ... implement in subclass\n // return [];\n }\n\n public serialMessage(code: string[] | Uint8Array<ArrayBufferLike> | string | ArrayBuffer): void {\n // this.dispatch('serial:message', code);\n // ... implement in subclass\n console.log(code);\n this.dispatch(\"serial:message\", { code: code });\n throw new Error(\"Method not implemented 'serialMessage'\");\n }\n\n public serialCorruptMessage(code: Uint8Array | number[] | string[] | never | null | string | ArrayBuffer): void {\n // ... implement in subclass\n console.log(code);\n this.dispatch(\"serial:corrupt-message\", { code });\n throw new Error(\"Method not implemented 'serialCorruptMessage'\");\n }\n\n #clearLastError(): void {\n this.__internal__.last_error = {\n message: null,\n action: null,\n code: null,\n no_code: 0,\n };\n }\n\n public clearSerialQueue(): void {\n this.__internal__.serial.queue = [];\n }\n\n public sumHex(arr: string[]): string {\n let sum: number = 0;\n arr.forEach((value: string): void => {\n sum += parseInt(value, 16);\n });\n return sum.toString(16);\n }\n\n public toString(): string {\n return JSON.stringify({\n __class: this.typeDevice,\n device_number: this.deviceNumber,\n uuid: this.uuid,\n connected: this.isConnected,\n connection: this.__internal__.serial.bytes_connection,\n });\n }\n\n public softReload(): void {\n this.#clearLastError();\n this.dispatch(\"serial:soft-reload\", {});\n }\n\n public async sendConnect(): Promise<void> {\n if (!this.__internal__.serial.bytes_connection) {\n throw new Error(\"No connection bytes defined\");\n }\n await this.appendToQueue(this.__internal__.serial.bytes_connection, \"connect\");\n }\n\n public async sendCustomCode({ code = [] }: CustomCode = { code: [] }): Promise<void> {\n if (!code) {\n throw new Error(\"No data to send\");\n }\n\n if (this.__internal__.bypassSerialBytesConnection) {\n this.__internal__.serial.bytes_connection = this.validateBytes(code);\n }\n\n await this.appendToQueue(code, \"custom\");\n }\n\n public stringToArrayHex(string: string): string[] {\n return Array.from(string).map((char: string): string => char.charCodeAt(0).toString(16));\n }\n\n public stringToArrayBuffer(string: string, end: string = \"\\n\"): ArrayBufferLike {\n return this.parseStringToTextEncoder(string, end).buffer;\n }\n\n public parseStringToTextEncoder(string: string = \"\", end: string = \"\\n\"): Uint8Array {\n const encoder = new TextEncoder();\n string += end; // to finish the command\n return encoder.encode(string);\n }\n\n public parseStringToBytes(string: string = \"\", end: string = \"\\n\"): string[] {\n const encoded: Uint8Array = this.parseStringToTextEncoder(string, end);\n return Array.from(encoded).map((byte: number): string => byte.toString(16));\n }\n\n public parseUint8ToHex(array: Uint8Array): string[] {\n return Array.from(array).map((byte: number): string => byte.toString(16).padStart(2, \"0\").toLowerCase());\n }\n\n public parseHexToUint8(array: string[]): Uint8Array {\n return new Uint8Array(array.map((hexString: string): number => parseInt(hexString, 16)));\n }\n\n public stringArrayToUint8Array(strings: string[]): Uint8Array {\n const bytes: number[] = [];\n if (typeof strings === \"string\") {\n return this.parseStringToTextEncoder(strings).buffer as unknown as Uint8Array;\n }\n strings.forEach((str: string): void => {\n const hex = str.replace(\"0x\", \"\");\n bytes.push(parseInt(hex, 16));\n });\n\n return new Uint8Array(bytes);\n }\n\n public parseUint8ArrayToString(array: Uint8Array | string[]): string {\n let arrayUint8: Uint8Array = new Uint8Array(0);\n if (array instanceof Uint8Array) {\n arrayUint8 = array;\n } else {\n arrayUint8 = this.stringArrayToUint8Array(array as string[]);\n }\n\n array = this.parseUint8ToHex(arrayUint8);\n const byteArray: number[] = array.map((hexString: string): number => parseInt(hexString, 16));\n if (this.__internal__.serial.response.replacer) {\n return String.fromCharCode(...byteArray).replace(this.__internal__.serial.response.replacer, \"\");\n }\n return String.fromCharCode(...byteArray);\n }\n\n public hexToAscii(hex: string | number): string {\n const hexString: string = hex.toString();\n let asciiString: string = \"\";\n for (let i: number = 0; i < hexString.length; i += 2) {\n asciiString += String.fromCharCode(parseInt(hexString.substring(i, 2), 16));\n }\n return asciiString;\n }\n\n public asciiToHex(asciiString: string): string {\n const hexArray: string[] = [];\n for (let i: number = 0, length: number = asciiString.length; i < length; i++) {\n const hex: string = Number(asciiString.charCodeAt(i)).toString(16);\n hexArray.push(hex);\n }\n return hexArray.join(\"\");\n }\n\n public $checkAndDispatchConnection(): boolean {\n return this.isConnected;\n }\n}\n","/**\n * Custom error codes for serial communication errors\n */\nexport enum SerialErrorCode {\n CONNECTION_FAILED = \"CONNECTION_FAILED\",\n DISCONNECTION_FAILED = \"DISCONNECTION_FAILED\",\n WRITE_FAILED = \"WRITE_FAILED\",\n READ_FAILED = \"READ_FAILED\",\n TIMEOUT = \"TIMEOUT\",\n PORT_NOT_FOUND = \"PORT_NOT_FOUND\",\n PERMISSION_DENIED = \"PERMISSION_DENIED\",\n DEVICE_NOT_SUPPORTED = \"DEVICE_NOT_SUPPORTED\",\n INVALID_CONFIGURATION = \"INVALID_CONFIGURATION\",\n SOCKET_ERROR = \"SOCKET_ERROR\",\n UNKNOWN_ERROR = \"UNKNOWN_ERROR\",\n}\n\n/**\n * Custom error class for WebSerial operations\n * Provides structured error information with codes and context\n * @extends Error\n */\nexport class SerialError extends Error {\n /**\n * Error code identifying the type of error\n */\n public readonly code: SerialErrorCode;\n\n /**\n * Additional context about the error\n */\n public readonly context?: Record<string, unknown>;\n\n /**\n * Timestamp when the error occurred\n */\n public readonly timestamp: Date;\n\n /**\n * Creates a new SerialError\n * @param message - Human-readable error message\n * @param code - Error code from SerialErrorCode enum\n * @param context - Additional context information\n * @example\n * ```typescript\n * throw new SerialError(\n * 'Failed to connect to device',\n * SerialErrorCode.CONNECTION_FAILED,\n * { port: 'COM3', baudRate: 9600 }\n * );\n * ```\n */\n constructor(\n message: string,\n code: SerialErrorCode = SerialErrorCode.UNKNOWN_ERROR,\n context?: Record<string, unknown>,\n ) {\n super(message);\n this.name = \"SerialError\";\n this.code = code;\n this.context = context;\n this.timestamp = new Date();\n\n // Maintains proper stack trace for where our error was thrown (only available on V8)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, SerialError);\n }\n }\n\n /**\n * Returns a JSON representation of the error\n * @returns Serialized error object\n */\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n context: this.context,\n timestamp: this.timestamp.toISOString(),\n stack: this.stack,\n };\n }\n\n /**\n * Returns a formatted string representation of the error\n * @returns Formatted error string\n */\n toString(): string {\n const contextStr = this.context ? ` | Context: ${JSON.stringify(this.context)}` : \"\";\n return `${this.name} [${this.code}]: ${this.message}${contextStr}`;\n }\n}\n"],"names":["SerialEvent","type","options","Dispatcher","data","event","ms","this1","callback","listener","l","key","Devices","device","error","id","device_number","devices","wait","resolve","MySocket","#uri","#options","#socket","#connected","#hasInstance","#boundedFun","uri","url","io","config","Socket","defaultConfigPort","Core","#boundFinishConnecting","filters","config_port","no_device","device_listen_on_channel","bypassSerialBytesConnection","socket","transformStream","#serialSetBytesConnection","#registerDefaultListeners","#internalEvents","channel","value","prevConnected","connected","#checkIfPortIsOpen","#disconnected","#connectingChange","limiter","length","bytes","path","vendorId","productId","string","port","detail","#onFinishConnecting","auxPrevConnected","#serialGetResponse","reject","interval","reader","output_stream","err","#serialSocketWrite","#serialWrite","#waitForCTS","writer","timeoutMs","start","clearToSend","code","corrupt","str","splited","s","arraybuffer","#serialPortsFiltered","ports","info","filter","aux","#appendBuffer","incoming","tmp","#transformStreamLoop","#freeSerialLoop","#slicedSerialLoop","expectedLength","buffer","message","#delimitedSerialLoop","prefixLimiter","sufixLimiter","decoded","messages","pattern","match","lastIndex","end","chunk","parts","part","msg","leftoverBytes","#readSerialLoop","parser","done","#forget","dec","hex","val","min","new_bytes","index","byte","#runQueue","onSerialSocketDisconnect","onSerialSocketConnect","#browserEvents","first","limit_response","e","copy_queue","arr","action","listen_on_port","#clearLastError","sum","char","encoder","encoded","array","hexString","strings","arrayUint8","byteArray","asciiString","hexArray","i","SerialErrorCode","SerialError","context","contextStr"],"mappings":"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"}
|