fix(led-tool): harden Web Serial raw REPL connect
Improve boot wait, readUntil buffer handling, and settings editor host/Web Serial flows after device reset. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -24,8 +24,10 @@
|
||||
let hostConnected = false;
|
||||
let hostConnectedPort = '';
|
||||
let transferBusy = false;
|
||||
let webConnectBusy = false;
|
||||
|
||||
const webSerialOk = window.LedToolWebSerial && window.LedToolWebSerial.supported();
|
||||
let webSerialGrantedCount = 0;
|
||||
|
||||
function setStatus(text, isError) {
|
||||
if (!statusEl) return;
|
||||
@@ -40,6 +42,17 @@
|
||||
setTimeout(() => messageEl.classList.remove('show'), 5000);
|
||||
}
|
||||
|
||||
function errorMessage(e) {
|
||||
if (!e) return 'Unknown error';
|
||||
if (typeof e === 'string') return e;
|
||||
return e.message || String(e);
|
||||
}
|
||||
|
||||
function onWebSerialTransferError(e) {
|
||||
if (webClient) webClient.inRawRepl = false;
|
||||
return errorMessage(e);
|
||||
}
|
||||
|
||||
function formToObject() {
|
||||
const out = {};
|
||||
document.querySelectorAll('[data-setting]').forEach((el) => {
|
||||
@@ -99,7 +112,11 @@
|
||||
} else if (hostOpen) {
|
||||
setStatus(`Host serial: ${hostConnectedPort} (use Download or Upload).`);
|
||||
} else if (webSerialOk) {
|
||||
setStatus('Connect host serial or Web Serial USB, then Download or Upload.');
|
||||
if (webSerialGrantedCount === 1) {
|
||||
setStatus('Connect USB (one remembered port) or host serial, then Download or Upload.');
|
||||
} else {
|
||||
setStatus('Connect host serial or Web Serial USB, then Download or Upload.');
|
||||
}
|
||||
} else {
|
||||
setStatus(`Connect host serial (default ${DEFAULT_HOST_PORT}).`);
|
||||
}
|
||||
@@ -205,21 +222,31 @@
|
||||
}
|
||||
|
||||
async function connectWebSerial() {
|
||||
if (webConnectBusy) return;
|
||||
if (!window.LedToolWebSerial || !window.LedToolWebSerial.supported()) {
|
||||
flash('Web Serial not supported (use Chrome or Edge over HTTPS or localhost).', true);
|
||||
return;
|
||||
}
|
||||
if (usingWebSerial()) {
|
||||
flash('USB already connected.', false);
|
||||
return;
|
||||
}
|
||||
if (usingHostSerial()) {
|
||||
disconnectHostSerial();
|
||||
}
|
||||
log('connectWebSerial: requestPort');
|
||||
setStatus('Opening USB port…');
|
||||
webPort = await window.LedToolWebSerial.requestPort();
|
||||
log('connectWebSerial: port selected', webPort);
|
||||
webClient = new window.LedToolWebSerial.MicroPythonRawRepl();
|
||||
await webClient.connect(webPort);
|
||||
updateUi();
|
||||
flash('USB port open. Use Download or Upload to talk to the device.', false);
|
||||
webConnectBusy = true;
|
||||
try {
|
||||
log('connectWebSerial: requestPort');
|
||||
setStatus('Opening USB port…');
|
||||
webPort = await window.LedToolWebSerial.requestPort();
|
||||
log('connectWebSerial: port selected', webPort);
|
||||
webClient = new window.LedToolWebSerial.MicroPythonRawRepl();
|
||||
await webClient.connect(webPort);
|
||||
updateUi();
|
||||
flash('USB port open. Wait for boot, then Download.', false);
|
||||
} finally {
|
||||
webConnectBusy = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function disconnectWebSerial() {
|
||||
@@ -284,9 +311,10 @@
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(LOG, 'download failed', e);
|
||||
if (rawJson) rawJson.value = String(e.message || e);
|
||||
flash(e.message, true);
|
||||
setStatus(e.message, true);
|
||||
const msg = usingWebSerial() ? onWebSerialTransferError(e) : errorMessage(e);
|
||||
if (rawJson) rawJson.value = msg;
|
||||
flash(msg, true);
|
||||
setStatus(msg, true);
|
||||
} finally {
|
||||
transferBusy = false;
|
||||
}
|
||||
@@ -310,8 +338,9 @@
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(LOG, 'upload failed', e);
|
||||
flash(e.message, true);
|
||||
setStatus(e.message, true);
|
||||
const msg = usingWebSerial() ? onWebSerialTransferError(e) : errorMessage(e);
|
||||
flash(msg, true);
|
||||
setStatus(msg, true);
|
||||
} finally {
|
||||
transferBusy = false;
|
||||
}
|
||||
@@ -374,7 +403,19 @@
|
||||
}
|
||||
});
|
||||
|
||||
async function refreshWebSerialGrantHint() {
|
||||
if (!webSerialOk || !window.LedToolWebSerial.getGrantedPorts) return;
|
||||
try {
|
||||
const ports = await window.LedToolWebSerial.getGrantedPorts();
|
||||
webSerialGrantedCount = ports.length;
|
||||
updateUi();
|
||||
} catch (_) {
|
||||
/* ignore */
|
||||
}
|
||||
}
|
||||
|
||||
log('settings editor ready', { apiBase, webSerialOk });
|
||||
updateUi();
|
||||
loadHostPorts();
|
||||
refreshWebSerialGrantHint();
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user