flasher.meshcore.dev/lib/console.js

98 lines
2.4 KiB
JavaScript
Raw Permalink Normal View History

2025-02-23 10:19:53 +01:00
function delay(msecs) {
return new Promise((resolve) => setTimeout(resolve, msecs));
}
2026-01-10 23:15:50 +01:00
2025-02-23 10:19:53 +01:00
class LineBreakTransformer {
chunks = '';
port = null;
transform(chunk, controller) {
// Append new chunks to existing chunks.
this.chunks += chunk;
// For each line breaks in chunks, send the parsed lines out.
const lines = this.chunks.split('\r\n');
this.chunks = lines.pop();
lines.forEach((line) => controller.enqueue(line + '\r\n'));
}
flush(controller) {
// When the stream is closed, flush any remaining chunks out.
controller.enqueue(this.chunks);
}
}
export class SerialConsole {
connected = false;
constructor(port) {
this.port = port;
this.controller = new AbortController();
this.signal = this.controller.signal;
this.onOutput = (text) => {
console.log(text);
};
}
async connect() {
try {
await this.port.open({ baudRate: 115200 });
this.connected = true;
await this.port.readable
.pipeThrough(new TextDecoderStream(), { signal: this.signal })
.pipeThrough(new TransformStream(new LineBreakTransformer()))
.pipeTo(
new WritableStream({
write: (chunk) => {
this.addLine(chunk.replace('\r', ''));
},
}),
);
// Check AFTER the pipeTo has completed (or been aborted)
if (!this.signal.aborted) {
this.addLine('\n\n*** Terminal disconnected');
this.connected = false;
}
} catch (e) {
this.addLine(`\n\n*** Terminal disconnected: ${e}`);
this.connected = false;
} finally {
await delay(100);
}
}
addLine(text) {
this.onOutput(text);
}
async sendCommand(command) {
const encoder = new TextEncoder();
const writer = this.port.writable.getWriter(); // Get writer from 'this.port'
await writer.write(encoder.encode(command + '\r\n'));
try {
writer.releaseLock();
} catch (err) {
console.error('Ignoring release lock error', err);
}
}
async disconnect() {
this.controller.abort();
await delay(50);
await this.port.close();
}
async reset() {
console.debug('Triggering reset');
await this.port.setSignals({
dataTerminalReady: false,
requestToSend: true,
});
await delay(250);
await this.port.setSignals({
dataTerminalReady: false,
requestToSend: false,
});
await delay(1250);
}
}