UNPKG

@danidoble/webserial

Version:
813 lines (812 loc) 33.2 kB
var V = Object.defineProperty, R = (n) => { throw TypeError(n); }, z = (n, e, t) => e in n ? V(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t, y = (n, e, t) => z(n, typeof e != "symbol" ? e + "" : e, t), T = (n, e, t) => e.has(n) || R("Cannot " + t), b = (n, e, t) => (T(n, e, "read from private field"), e.get(n)), S = (n, e, t) => e.has(n) ? R("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(n) : e.set(n, t), J = (n, e, t, i) => (T(n, e, "write to private field"), e.set(n, t), t), l = (n, e, t) => (T(n, e, "access private method"), t); class A extends CustomEvent { constructor(e, t) { super(e, t); } } class I extends EventTarget { constructor() { super(...arguments), y(this, "__listeners__", { debug: !1 }), y(this, "__debug__", !1), y(this, "__listenersCallbacks__", []); } dispatch(e, t = null) { const i = new A(e, { detail: t }); this.dispatchEvent(i), this.__debug__ && this.dispatchEvent(new A("debug", { detail: { type: e, data: t } })); } dispatchAsync(e, t = null, i = 100) { const s = this; setTimeout(() => { s.dispatch(e, t); }, i); } on(e, t) { typeof this.__listeners__[e] < "u" && !this.__listeners__[e] && (this.__listeners__[e] = !0), this.__listenersCallbacks__.push({ key: e, callback: t }), this.addEventListener(e, t); } off(e, t) { this.__listenersCallbacks__ = this.__listenersCallbacks__.filter((i) => !(i.key === e && i.callback === t)), this.removeEventListener(e, t); } serialRegisterAvailableListener(e) { this.__listeners__[e] || (this.__listeners__[e] = !1); } get availableListeners() { return Object.keys(this.__listeners__).sort().map((e) => ({ type: e, listening: this.__listeners__[e] })); } removeAllListeners() { for (const e of this.__listenersCallbacks__) ["internal:queue"].includes(e.key) || (this.__listenersCallbacks__ = this.__listenersCallbacks__.filter((t) => !(t.key === e.key && t.callback === e.callback)), this.removeEventListener(e.key, e.callback)); for (const e of Object.keys(this.__listeners__)) this.__listeners__[e] = !1; } } const C = class a extends I { constructor() { super(), ["change"].forEach((e) => { this.serialRegisterAvailableListener(e); }); } static $dispatchChange(e = null) { e && e.$checkAndDispatchConnection(), a.instance.dispatch("change", { devices: a.devices, dispatcher: e }); } static typeError(e) { const t = new Error(); throw t.message = `Type ${e} is not supported`, t.name = "DeviceTypeError", t; } static registerType(e) { typeof a.devices[e] > "u" && (a.devices = { ...a.devices, [e]: {} }); } static add(e) { const t = e.typeDevice; typeof a.devices[t] > "u" && a.registerType(t); const i = e.uuid; if (typeof a.devices[t] > "u" && a.typeError(t), a.devices[t][i]) throw new Error(`Device with id ${i} already exists`); return a.devices[t][i] = e, a.$dispatchChange(e), Object.keys(a.devices[t]).indexOf(i); } static get(e, t) { return typeof a.devices[e] > "u" && a.registerType(e), typeof a.devices[e] > "u" && a.typeError(e), a.devices[e][t]; } static getAll(e = null) { return e === null ? a.devices : (typeof a.devices[e] > "u" && a.typeError(e), a.devices[e]); } static getList() { return Object.values(a.devices).map((e) => Object.values(e)).flat(); } static getByNumber(e, t) { return typeof a.devices[e] > "u" && a.typeError(e), Object.values(a.devices[e]).find((i) => i.deviceNumber === t) ?? null; } static getCustom(e, t = 1) { return typeof a.devices[e] > "u" && a.typeError(e), Object.values(a.devices[e]).find((i) => i.deviceNumber === t) ?? null; } static async connectToAll() { const e = a.getList(); for (const t of e) t.isConnected || await t.connect().catch(console.warn); return Promise.resolve(a.areAllConnected()); } static async disconnectAll() { const e = a.getList(); for (const t of e) t.isDisconnected || await t.disconnect().catch(console.warn); return Promise.resolve(a.areAllDisconnected()); } static async areAllConnected() { const e = a.getList(); for (const t of e) if (!t.isConnected) return Promise.resolve(!1); return Promise.resolve(!0); } static async areAllDisconnected() { const e = a.getList(); for (const t of e) if (!t.isDisconnected) return Promise.resolve(!1); return Promise.resolve(!0); } static async getAllConnected() { const e = a.getList(); return Promise.resolve(e.filter((t) => t.isConnected)); } static async getAllDisconnected() { const e = a.getList(); return Promise.resolve(e.filter((t) => t.isDisconnected)); } }; y(C, "instance"), y(C, "devices", {}); let c = C; c.instance || (c.instance = new c()); function M(n = 100) { return new Promise( (e) => setTimeout(() => e(), n) ); } function G() { return "serial" in navigator; } const v = { baudRate: 9600, dataBits: 8, stopBits: 1, parity: "none", bufferSize: 32768, flowControl: "none" }; var p, r, f, m, q, x, k, u, N, L, D, B, P, O, g, H, j, F, U, $, W, Q; class K extends I { constructor({ filters: e = null, config_port: t = v, no_device: i = 1, device_listen_on_channel: s = 1, bypassSerialBytesConnection: o = !1 } = { filters: null, config_port: v, no_device: 1, device_listen_on_channel: 1, bypassSerialBytesConnection: !1 }) { if (super(), S(this, r), y(this, "__internal__", { bypassSerialBytesConnection: !1, auto_response: !1, device_number: 1, aux_port_connector: 0, last_error: { message: null, action: null, code: null, no_code: 0 }, serial: { aux_connecting: "idle", connecting: !1, connected: !1, port: null, last_action: null, response: { length: null, buffer: new Uint8Array([]), as: "uint8", replacer: /[\n\r]+/g, limiter: null, prefixLimiter: !1, sufixLimiter: !0, delimited: !1 }, reader: null, input_done: null, output_done: null, input_stream: null, output_stream: null, keep_reading: !0, time_until_send_bytes: void 0, delay_first_connection: 200, bytes_connection: null, filters: [], config_port: v, queue: [], auto_response: ["DD", "DD"], free_timeout_ms: 50, // In previous versions 400 was used useRTSCTS: !1 // Use RTS/CTS flow control }, device: { type: "unknown", id: window.crypto.randomUUID(), listen_on_port: null }, time: { response_connection: 500, response_general: 2e3 }, timeout: { until_response: 0 }, interval: { reconnection: 0 } }), S(this, p, null), !("serial" in navigator)) throw new Error("Web Serial not supported"); e && (this.serialFilters = e), t && (this.serialConfigPort = t), o && (this.__internal__.bypassSerialBytesConnection = o), i && l(this, r, W).call(this, i), s && ["number", "string"].includes(typeof s) && (this.listenOnChannel = s), l(this, r, j).call(this), l(this, r, F).call(this); } set listenOnChannel(e) { if (typeof e == "string" && (e = parseInt(e)), isNaN(e) || e < 1 || e > 255) throw new Error("Invalid port number"); this.__internal__.device.listen_on_port = e, !this.__internal__.bypassSerialBytesConnection && (this.__internal__.serial.bytes_connection = this.serialSetConnectionConstant(e)); } get lastAction() { return this.__internal__.serial.last_action; } get listenOnChannel() { return this.__internal__.device.listen_on_port ?? 1; } set serialFilters(e) { if (this.isConnected) throw new Error("Cannot change serial filters while connected"); this.__internal__.serial.filters = e; } get serialFilters() { return this.__internal__.serial.filters; } set serialConfigPort(e) { if (this.isConnected) throw new Error("Cannot change serial filters while connected"); this.__internal__.serial.config_port = e; } get serialConfigPort() { return this.__internal__.serial.config_port; } get useRTSCTS() { return this.__internal__.serial.useRTSCTS; } set useRTSCTS(e) { this.__internal__.serial.useRTSCTS = e; } get isConnected() { const e = this.__internal__.serial.connected, t = l(this, r, f).call(this, this.__internal__.serial.port); return e && !t && l(this, r, m).call(this, { error: "Port is closed, not readable or writable." }), this.__internal__.serial.connected = t, this.__internal__.serial.connected; } get isConnecting() { return this.__internal__.serial.connecting; } get isDisconnected() { const e = this.__internal__.serial.connected, t = l(this, r, f).call(this, this.__internal__.serial.port); return !e && t && (this.dispatch("serial:connected"), l(this, r, g).call(this, !1), c.$dispatchChange(this)), this.__internal__.serial.connected = t, !this.__internal__.serial.connected; } get deviceNumber() { return this.__internal__.device_number; } get uuid() { return this.__internal__.device.id; } get typeDevice() { return this.__internal__.device.type; } get queue() { return this.__internal__.serial.queue; } get responseDelimited() { return this.__internal__.serial.response.delimited; } set responseDelimited(e) { if (typeof e != "boolean") throw new Error("responseDelimited must be a boolean"); this.__internal__.serial.response.delimited = e; } get responsePrefixLimited() { return this.__internal__.serial.response.prefixLimiter; } set responsePrefixLimited(e) { if (typeof e != "boolean") throw new Error("responsePrefixLimited must be a boolean"); this.__internal__.serial.response.prefixLimiter = e; } get responseSufixLimited() { return this.__internal__.serial.response.sufixLimiter; } set responseSufixLimited(e) { if (typeof e != "boolean") throw new Error("responseSufixLimited must be a boolean"); this.__internal__.serial.response.sufixLimiter = e; } get responseLimiter() { return this.__internal__.serial.response.limiter; } set responseLimiter(e) { if (typeof e != "string" && !(e instanceof RegExp)) throw new Error("responseLimiter must be a string or a RegExp"); this.__internal__.serial.response.limiter = e; } get fixedBytesMessage() { return this.__internal__.serial.response.length; } set fixedBytesMessage(e) { if (e !== null && (typeof e != "number" || e < 1)) throw new Error("Invalid length for fixed bytes message"); this.__internal__.serial.response.length = e; } get timeoutBeforeResponseBytes() { return this.__internal__.serial.free_timeout_ms || 50; } set timeoutBeforeResponseBytes(e) { if (e !== void 0 && (typeof e != "number" || e < 1)) throw new Error("Invalid timeout for response bytes"); this.__internal__.serial.free_timeout_ms = e ?? 50; } get bypassSerialBytesConnection() { return this.__internal__.bypassSerialBytesConnection; } set bypassSerialBytesConnection(e) { if (typeof e != "boolean") throw new Error("bypassSerialBytesConnection must be a boolean"); this.__internal__.bypassSerialBytesConnection = e; } async timeout(e, t) { this.__internal__.last_error.message = "Operation response timed out.", this.__internal__.last_error.action = t, this.__internal__.last_error.code = e, this.__internal__.timeout.until_response && (clearTimeout(this.__internal__.timeout.until_response), this.__internal__.timeout.until_response = 0), t === "connect" ? (this.__internal__.serial.connected = !1, this.dispatch("serial:reconnect", {}), c.$dispatchChange(this)) : t === "connection:start" && (await this.serialDisconnect(), this.__internal__.serial.connected = !1, this.__internal__.aux_port_connector += 1, c.$dispatchChange(this), await this.serialConnect()), this.dispatch("serial:timeout", { ...this.__internal__.last_error, bytes: e, action: t }); } async disconnect(e = null) { await this.serialDisconnect(), l(this, r, m).call(this, e); } async connect() { return this.isConnected ? !0 : (this.__internal__.serial.aux_connecting = "idle", new Promise((e, t) => { G() || t("Web Serial not supported"), b(this, p) || J(this, p, l(this, r, q).bind(this)), this.on("internal:connecting", b(this, p)); const i = setInterval(() => { this.__internal__.serial.aux_connecting === "finished" ? (clearInterval(i), this.__internal__.serial.aux_connecting = "idle", b(this, p) !== null && this.off("internal:connecting", b(this, p)), this.isConnected ? e(!0) : t(`${this.typeDevice} device ${this.deviceNumber} not connected`)) : this.__internal__.serial.aux_connecting === "connecting" && (this.__internal__.serial.aux_connecting = "idle", this.dispatch("internal:connecting", { active: !0 }), this.dispatch("serial:connecting", { active: !0 })); }, 100); this.serialConnect(); })); } async serialDisconnect() { try { const e = this.__internal__.serial.reader, t = this.__internal__.serial.output_stream; e && (await e.cancel().catch((i) => this.serialErrors(i)), await this.__internal__.serial.input_done), t && (await t.getWriter().close(), await this.__internal__.serial.output_done), this.__internal__.serial.connected && this.__internal__.serial && this.__internal__.serial.port && await this.__internal__.serial.port.close(); } catch (e) { this.serialErrors(e); } finally { this.__internal__.serial.reader = null, this.__internal__.serial.input_done = null, this.__internal__.serial.output_stream = null, this.__internal__.serial.output_done = null, this.__internal__.serial.connected = !1, this.__internal__.serial.port = null, c.$dispatchChange(this); } } getResponseAsArrayBuffer() { this.__internal__.serial.response.as = "arraybuffer"; } getResponseAsArrayHex() { this.__internal__.serial.response.as = "hex"; } getResponseAsUint8Array() { this.__internal__.serial.response.as = "uint8"; } getResponseAsString() { this.__internal__.serial.response.as = "string"; } async serialPortsSaved(e) { const t = this.serialFilters; if (this.__internal__.aux_port_connector < e.length) { const i = this.__internal__.aux_port_connector; this.__internal__.serial.port = e[i]; } else this.__internal__.aux_port_connector = 0, this.__internal__.serial.port = await navigator.serial.requestPort({ filters: t }); if (!this.__internal__.serial.port) throw new Error("Select another port please"); } serialErrors(e) { const t = e.toString().toLowerCase(); switch (!0) { case t.includes("must be handling a user gesture to show a permission request"): case t.includes("the port is closed."): case t.includes("the port is closed or is not writable"): case t.includes("the port is closed or is not readable"): case t.includes("the port is closed or is not readable/writable"): case t.includes("select another port please"): case t.includes("no port selected by the user"): case t.includes( "this readable stream reader has been released and cannot be used to cancel its previous owner stream" ): this.dispatch("serial:need-permission", {}), c.$dispatchChange(this); break; case t.includes("the port is already open."): case t.includes("failed to open serial port"): this.serialDisconnect().then(async () => { this.__internal__.aux_port_connector += 1, await this.serialConnect(); }); break; case t.includes("cannot read properties of undefined (reading 'writable')"): case t.includes("cannot read properties of null (reading 'writable')"): case t.includes("cannot read property 'writable' of null"): case t.includes("cannot read property 'writable' of undefined"): this.serialDisconnect().then(async () => { await this.serialConnect(); }); break; case t.includes("'close' on 'serialport': a call to close() is already in progress."): break; case t.includes("failed to execute 'open' on 'serialport': a call to open() is already in progress."): break; case t.includes("the port is already closed."): break; case t.includes("the device has been lost"): this.dispatch("serial:lost", {}), c.$dispatchChange(this); break; case t.includes("navigator.serial is undefined"): this.dispatch("serial:unsupported", {}); break; default: console.error(e); break; } this.dispatch("serial:error", e); } async serialConnect() { try { l(this, r, g).call(this, !0); const e = await l(this, r, N).call(this); if (e.length > 0) await this.serialPortsSaved(e); else { const s = this.serialFilters; this.__internal__.serial.port = await navigator.serial.requestPort({ filters: s }); } const t = this.__internal__.serial.port; if (!t) throw new Error("No port selected by the user"); await t.open(this.serialConfigPort); const i = this; t.onconnect = (s) => { var o; i.dispatch("serial:connected", s), l(o = i, r, g).call(o, !1), c.$dispatchChange(this), i.__internal__.serial.queue.length > 0 && i.dispatch("internal:queue", {}); }, t.ondisconnect = async () => { await i.disconnect(); }, await M(this.__internal__.serial.delay_first_connection), this.__internal__.timeout.until_response = setTimeout(async () => { await i.timeout(i.__internal__.serial.bytes_connection ?? [], "connection:start"); }, this.__internal__.time.response_connection), this.__internal__.serial.last_action = "connect", await l(this, r, x).call(this, this.__internal__.serial.bytes_connection ?? []), this.dispatch("serial:sent", { action: "connect", bytes: this.__internal__.serial.bytes_connection }), this.__internal__.auto_response && l(this, r, u).call(this, this.__internal__.serial.auto_response), await l(this, r, O).call(this); } catch (e) { l(this, r, g).call(this, !1), this.serialErrors(e); } } async serialForget() { return await l(this, r, H).call(this); } decToHex(e) { return typeof e == "string" && (e = parseInt(e, 10)), e.toString(16); } hexToDec(e) { return parseInt(e, 16); } hexMaker(e = "00", t = 2) { return e.toString().padStart(t, "0").toLowerCase(); } add0x(e) { const t = []; return e.forEach((i, s) => { t[s] = "0x" + i; }), t; } bytesToHex(e) { return this.add0x(Array.from(e, (t) => this.hexMaker(t))); } validateBytes(e) { let t = new Uint8Array(0); if (e instanceof Uint8Array) t = e; else if (typeof e == "string") t = this.parseStringToTextEncoder(e); else if (Array.isArray(e) && typeof e[0] == "string") t = this.stringArrayToUint8Array(e); else if (Array.isArray(e) && typeof e[0] == "number") t = new Uint8Array(e); else throw new Error("Invalid data type"); return t; } async appendToQueue(e, t) { const i = this.validateBytes(e); if (["connect", "connection:start"].includes(t)) { if (this.__internal__.serial.connected) return; await this.serialConnect(); return; } this.__internal__.serial.queue.push({ bytes: i, action: t }), this.dispatch("internal:queue", {}); } serialSetConnectionConstant(e = 1) { if (this.__internal__.bypassSerialBytesConnection) return this.__internal__.serial.bytes_connection; throw new Error(`Method not implemented 'serialSetConnectionConstant' to listen on channel ${e}`); } serialMessage(e) { throw console.log(e), this.dispatch("serial:message", { code: e }), new Error("Method not implemented 'serialMessage'"); } serialCorruptMessage(e) { throw console.log(e), this.dispatch("serial:corrupt-message", { code: e }), new Error("Method not implemented 'serialCorruptMessage'"); } clearSerialQueue() { this.__internal__.serial.queue = []; } sumHex(e) { let t = 0; return e.forEach((i) => { t += parseInt(i, 16); }), t.toString(16); } toString() { return JSON.stringify({ __class: this.typeDevice, device_number: this.deviceNumber, uuid: this.uuid, connected: this.isConnected, connection: this.__internal__.serial.bytes_connection }); } softReload() { l(this, r, Q).call(this), this.dispatch("serial:soft-reload", {}); } async sendConnect() { if (!this.__internal__.serial.bytes_connection) throw new Error("No connection bytes defined"); await this.appendToQueue(this.__internal__.serial.bytes_connection, "connect"); } async sendCustomCode({ code: e = [] } = { code: [] }) { if (!e) throw new Error("No data to send"); this.__internal__.bypassSerialBytesConnection && (this.__internal__.serial.bytes_connection = this.validateBytes(e)), await this.appendToQueue(e, "custom"); } stringToArrayHex(e) { return Array.from(e).map((t) => t.charCodeAt(0).toString(16)); } stringToArrayBuffer(e, t = ` `) { return this.parseStringToTextEncoder(e, t).buffer; } parseStringToTextEncoder(e = "", t = ` `) { const i = new TextEncoder(); return e += t, i.encode(e); } parseStringToBytes(e = "", t = ` `) { const i = this.parseStringToTextEncoder(e, t); return Array.from(i).map((s) => s.toString(16)); } parseUint8ToHex(e) { return Array.from(e).map((t) => t.toString(16)); } parseHexToUint8(e) { return new Uint8Array(e.map((t) => parseInt(t, 16))); } stringArrayToUint8Array(e) { const t = []; return typeof e == "string" ? this.parseStringToTextEncoder(e).buffer : (e.forEach((i) => { const s = i.replace("0x", ""); t.push(parseInt(s, 16)); }), new Uint8Array(t)); } parseUint8ArrayToString(e) { let t = new Uint8Array(0); e instanceof Uint8Array ? t = e : t = this.stringArrayToUint8Array(e), e = this.parseUint8ToHex(t); const i = e.map((s) => parseInt(s, 16)); return this.__internal__.serial.response.replacer ? String.fromCharCode(...i).replace(this.__internal__.serial.response.replacer, "") : String.fromCharCode(...i); } hexToAscii(e) { const t = e.toString(); let i = ""; for (let s = 0; s < t.length; s += 2) i += String.fromCharCode(parseInt(t.substring(s, 2), 16)); return i; } asciiToHex(e) { const t = []; for (let i = 0, s = e.length; i < s; i++) { const o = Number(e.charCodeAt(i)).toString(16); t.push(o); } return t.join(""); } $checkAndDispatchConnection() { return this.isConnected; } } p = /* @__PURE__ */ new WeakMap(), r = /* @__PURE__ */ new WeakSet(), f = function(n) { return !!(n && n.readable && n.writable); }, m = function(n = null) { this.__internal__.serial.connected = !1, this.__internal__.aux_port_connector = 0, this.dispatch("serial:disconnected", n), c.$dispatchChange(this); }, q = function(n) { this.__internal__.serial.aux_connecting = n.detail.active ? "connecting" : "finished"; }, x = async function(n) { const e = this.__internal__.serial.port; if (!e || e && (!e.readable || !e.writable)) throw l(this, r, m).call(this, { error: "Port is closed, not readable or writable." }), new Error("The port is closed or is not readable/writable"); const t = this.validateBytes(n); if (this.useRTSCTS && await l(this, r, k).call(this, e, 5e3), e.writable === null) return; const i = e.writable.getWriter(); await i.write(t), i.releaseLock(); }, k = async function(n, e = 5e3) { const t = Date.now(); for (; ; ) { if (Date.now() - t > e) throw new Error("Timeout waiting for clearToSend signal"); const { clearToSend: i } = await n.getSignals(); if (i) return; await M(100); } }, u = function(n = new Uint8Array([]), e = !1) { if (n && n.length > 0) { const t = this.__internal__.serial.connected; if (this.__internal__.serial.connected = l(this, r, f).call(this, this.__internal__.serial.port), c.$dispatchChange(this), !t && this.__internal__.serial.connected && (this.dispatch("serial:connected"), l(this, r, g).call(this, !1)), this.__internal__.interval.reconnection && (clearInterval(this.__internal__.interval.reconnection), this.__internal__.interval.reconnection = 0), this.__internal__.timeout.until_response && (clearTimeout(this.__internal__.timeout.until_response), this.__internal__.timeout.until_response = 0), this.__internal__.serial.response.as === "hex") e ? this.serialCorruptMessage(this.parseUint8ToHex(n)) : this.serialMessage(this.parseUint8ToHex(n)); else if (this.__internal__.serial.response.as === "uint8") e ? this.serialCorruptMessage(n) : this.serialMessage(n); else if (this.__internal__.serial.response.as === "string") { const i = this.parseUint8ArrayToString(n); if (this.__internal__.serial.response.limiter !== null) { const s = i.split(this.__internal__.serial.response.limiter); for (const o in s) s[o] && (e ? this.serialCorruptMessage(s[o]) : this.serialMessage(s[o])); } else e ? this.serialCorruptMessage(i) : this.serialMessage(i); } else { const i = this.stringToArrayBuffer(this.parseUint8ArrayToString(n)); e ? this.serialCorruptMessage(i) : this.serialMessage(i); } } this.__internal__.serial.queue.length !== 0 && this.dispatch("internal:queue", {}); }, N = async function() { const n = this.serialFilters, e = await navigator.serial.getPorts({ filters: n }); return n.length === 0 ? e : e.filter((t) => { const i = t.getInfo(); return n.some((s) => i.usbProductId === s.usbProductId && i.usbVendorId === s.usbVendorId); }).filter((t) => !l(this, r, f).call(this, t)); }, L = function(n) { if (n) { const e = this.__internal__.serial.response.buffer, t = new Uint8Array(e.length + n.byteLength); t.set(e, 0), t.set(new Uint8Array(n), e.length), this.__internal__.serial.response.buffer = t; } }, D = async function() { this.__internal__.serial.time_until_send_bytes && (clearTimeout(this.__internal__.serial.time_until_send_bytes), this.__internal__.serial.time_until_send_bytes = 0), this.__internal__.serial.time_until_send_bytes = setTimeout(() => { this.__internal__.serial.response.buffer && l(this, r, u).call(this, this.__internal__.serial.response.buffer), this.__internal__.serial.response.buffer = new Uint8Array(0); }, this.__internal__.serial.free_timeout_ms || 50); }, B = async function() { const n = this.__internal__.serial.response.length; let e = this.__internal__.serial.response.buffer; if (this.__internal__.serial.time_until_send_bytes && (clearTimeout(this.__internal__.serial.time_until_send_bytes), this.__internal__.serial.time_until_send_bytes = 0), !(n === null || !e || e.length === 0)) { for (; e.length >= n; ) { const t = e.slice(0, n); l(this, r, u).call(this, t), e = e.slice(n); } this.__internal__.serial.response.buffer = e, e.length > 0 && (this.__internal__.serial.time_until_send_bytes = setTimeout(() => { l(this, r, u).call(this, this.__internal__.serial.response.buffer, !0); }, this.__internal__.serial.free_timeout_ms || 50)); } }, P = async function() { const { limiter: n, prefixLimiter: e = !1, sufixLimiter: t = !0 } = this.__internal__.serial.response; if (!n) throw new Error("No limiter defined for delimited serial response"); const i = this.__internal__.serial.response.buffer; if (!n || !i || i.length === 0) return; this.__internal__.serial.time_until_send_bytes && (clearTimeout(this.__internal__.serial.time_until_send_bytes), this.__internal__.serial.time_until_send_bytes = 0); let s = new TextDecoder().decode(i); const o = []; if (typeof n == "string") { let _; if (e && t) _ = new RegExp(`${n}([^${n}]+)${n}`, "g"); else if (e) _ = new RegExp(`${n}([^${n}]*)`, "g"); else if (t) _ = new RegExp(`([^${n}]+)${n}`, "g"); else return; let d, h = 0; for (; (d = _.exec(s)) !== null; ) o.push(new TextEncoder().encode(d[1])), h = _.lastIndex; s = s.slice(h); } else if (n instanceof RegExp) { let _, d = 0; if (e && t) { const h = new RegExp(`${n.source}(.*?)${n.source}`, "g"); for (; (_ = h.exec(s)) !== null; ) o.push(new TextEncoder().encode(_[1])), d = h.lastIndex; } else if (t) for (; (_ = n.exec(s)) !== null; ) { const h = _.index, w = s.slice(d, h); o.push(new TextEncoder().encode(w)), d = n.lastIndex; } else if (e) { const h = s.split(n); h.shift(); for (const w of h) o.push(new TextEncoder().encode(w)); s = ""; } s = s.slice(d); } for (const _ of o) l(this, r, u).call(this, _); const E = new TextEncoder().encode(s); this.__internal__.serial.response.buffer = E, E.length > 0 && (this.__internal__.serial.time_until_send_bytes = setTimeout(() => { l(this, r, u).call(this, this.__internal__.serial.response.buffer, !0), this.__internal__.serial.response.buffer = new Uint8Array(0); }, this.__internal__.serial.free_timeout_ms ?? 50)); }, O = async function() { const n = this.__internal__.serial.port; if (!n || !n.readable) throw new Error("Port is not readable"); const e = n.readable.getReader(); this.__internal__.serial.reader = e; try { for (; this.__internal__.serial.keep_reading; ) { const { value: t, done: i } = await e.read(); if (i) break; l(this, r, L).call(this, t), this.__internal__.serial.response.delimited ? await l(this, r, P).call(this) : this.__internal__.serial.response.length === null ? await l(this, r, D).call(this) : await l(this, r, B).call(this); } } catch (t) { this.serialErrors(t); } finally { e.releaseLock(), this.__internal__.serial.keep_reading = !0, this.__internal__.serial.port && await this.__internal__.serial.port.close(); } }, g = function(n) { n !== this.__internal__.serial.connecting && (this.__internal__.serial.connecting = n, this.dispatch("serial:connecting", { active: n }), this.dispatch("internal:connecting", { active: n })); }, H = async function() { return typeof window > "u" ? !1 : "serial" in navigator && "forget" in SerialPort.prototype && this.__internal__.serial.port ? (await this.__internal__.serial.port.forget(), !0) : !1; }, j = function() { [ "serial:connected", "serial:connecting", "serial:reconnect", "serial:timeout", "serial:disconnected", "serial:sent", "serial:soft-reload", "serial:message", "serial:corrupt-message", "unknown", "serial:need-permission", "serial:lost", "serial:unsupported", "serial:error", "debug" ].forEach((n) => { this.serialRegisterAvailableListener(n); }); }, F = function() { const n = this; this.on("internal:queue", async () => { var e; await l(e = n, r, $).call(e); }), l(this, r, U).call(this); }, U = function() { const n = this; navigator.serial.addEventListener("connect", async () => { n.isDisconnected && await n.serialConnect().catch(() => { }); }); }, $ = async function() { if (!l(this, r, f).call(this, this.__internal__.serial.port)) { l(this, r, m).call(this, { error: "Port is closed, not readable or writable." }), await this.serialConnect(); return; } if (this.__internal__.timeout.until_response || this.__internal__.serial.queue.length === 0) return; const n = this.__internal__.serial.queue[0]; let e = this.__internal__.time.response_general; if (n.action === "connect" && (e = this.__internal__.time.response_connection), this.__internal__.timeout.until_response = setTimeout(async () => { await this.timeout(n.bytes, n.action); }, e), this.__internal__.serial.last_action = n.action ?? "unknown", await l(this, r, x).call(this, n.bytes), this.dispatch("serial:sent", { action: n.action, bytes: n.bytes }), this.__internal__.auto_response) { let i = new Uint8Array(0); try { i = this.validateBytes(this.__internal__.serial.auto_response); } catch (s) { this.serialErrors(s); } l(this, r, u).call(this, i); } const t = [...this.__internal__.serial.queue]; this.__internal__.serial.queue = t.splice(1); }, W = function(n = 1) { this.__internal__.device_number = n, !this.__internal__.bypassSerialBytesConnection && (this.__internal__.serial.bytes_connection = this.serialSetConnectionConstant(n)); }, Q = function() { this.__internal__.last_error = { message: null, action: null, code: null, no_code: 0 }; }; export { K as Z, c as h };