import SerialConnection from './serial_connection.js'; class WebSerialConnection extends SerialConnection { constructor(serialPort) { super(); this.serialPort = serialPort; this.reader = serialPort.readable.getReader(); this.writable = serialPort.writable; this.readLoop(); // listen for disconnect this.serialPort.addEventListener('disconnect', () => { this.onDisconnected(); }); // fire connected callback after constructor has returned setTimeout(async () => { await this.onConnected(); }, 0); } static async open() { // ensure browser supports web serial if (!navigator.serial) { alert('Web Serial is not supported in this browser'); return null; } // ask user to select device const serialPort = await navigator.serial.requestPort({ filters: [], }); // open port await serialPort.open({ baudRate: 115200, }); return new WebSerialConnection(serialPort); } async close() { // release reader lock try { this.reader.releaseLock(); } catch (e) { // console.log("failed to release lock on serial port readable, ignoring...", e); } // close serial port try { await this.serialPort.close(); } catch (e) { // console.log("failed to close serial port, ignoring...", e); } } /* override */ async write(bytes) { const writer = this.writable.getWriter(); try { await writer.write(new Uint8Array(bytes)); } finally { writer.releaseLock(); } } async readLoop() { try { while (true) { // read bytes until reader indicates it's done const { value, done } = await this.reader.read(); if (done) { break; } // pass to super class handler await this.onDataReceived(value); } } catch (error) { // ignore error if reader was released if (error instanceof TypeError) { return; } console.error('Error reading from serial port: ', error); } finally { this.reader.releaseLock(); } } } export default WebSerialConnection;