UNPKG

@danidoble/webserial

Version:
5 lines (4 loc) 27 kB
"use strict";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;_.instance||(_.instance=new _);function M(n=100){return new Promise(e=>setTimeout(()=>e(),n))}function Z(){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 G 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,useRTSCTS:!1},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),_.$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",{}),_.$dispatchChange(this)):t==="connection:start"&&(await this.serialDisconnect(),this.__internal__.serial.connected=!1,this.__internal__.aux_port_connector+=1,_.$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)=>{Z()||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,_.$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",{}),_.$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",{}),_.$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),_.$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=new WeakMap,r=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),_.$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),_.$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 c;if(e&&t)c=new RegExp(`${n}([^${n}]+)${n}`,"g");else if(e)c=new RegExp(`${n}([^${n}]*)`,"g");else if(t)c=new RegExp(`([^${n}]+)${n}`,"g");else return;let d,h=0;for(;(d=c.exec(s))!==null;)o.push(new TextEncoder().encode(d[1])),h=c.lastIndex;s=s.slice(h)}else if(n instanceof RegExp){let c,d=0;if(e&&t){const h=new RegExp(`${n.source}(.*?)${n.source}`,"g");for(;(c=h.exec(s))!==null;)o.push(new TextEncoder().encode(c[1])),d=h.lastIndex}else if(t)for(;(c=n.exec(s))!==null;){const h=c.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 c of o)l(this,r,u).call(this,c);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}};exports.Z=G;exports.h=_;