fix: Bluetooth chooser reply listener leak + serial path for OS-paired Classic printers#268
Conversation
select-bluetooth-device fires repeatedly per chooser session; registering an ipcMain.once listener per firing queued stale callbacks that consumed real selections FIFO. Keep one persistent listener holding the latest callback.
serial-discovery lists /dev/cu.* (macOS) / serial ports (Linux) via serialport; print-raw-serial writes raw ESC/POS bytes with open/write/drain/close + timeout. Windows excluded — the spooler path covers paired printers there.
debug/ms escape the @serialport namespace copy and must ship as runtime externals — the packaged-require test now loads serialport from the packaged tree like usb. A timed-out print no longer writes when open() resolves late; empty serial device keys are rejected up front.
|
Warning Review limit reached
More reviews will be available in 1 hour, 43 minutes, and 24 seconds. Learn how PR review limits work. To continue reviewing without waiting, purchase usage credits in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Repository: wcpos/coderabbit/.coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (10)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Why
Users on the 1.9.3 Windows desktop app report the Bluetooth "Scan for printers" button "does nothing". Live diagnosis (macOS dev, instrumented main process) found two issues in the Web Bluetooth chooser flow, plus a structural gap: Web Bluetooth is BLE-only, so Bluetooth Classic printers (most receipt printers) can never appear in the scan.
What
1.
select-bluetooth-devicelistener leak fixed (src/main/bluetooth-select.ts)Chromium fires
select-bluetooth-devicerepeatedly during onerequestDevice()chooser session. The old code registered a newipcMain.once('bluetooth-device-selected')listener per firing; stale listeners queued FIFO, so a later real selection was consumed by a dead callback and silently dropped. Now one persistent reply listener per window holds the latest chooser callback (invoked exactly once, scoped byevent.sender, removed on window close).2. Serial printing path for OS-paired Bluetooth Classic printers (
src/main/serial-printer.ts)Classic printers paired at the OS level surface as serial devices (
/dev/cu.*on macOS,/dev/rfcomm*on Linux). New IPC channels:serial-discovery— enumerates ports viaserialport, filters macOS noise (Bluetooth-Incoming-Portetc.), returns{id: 'serial:<path>', name}[]; empty on win32 (the spooler path covers paired printers there).print-raw-serial— validates byte payloads, writes via open→write→drain→close with a 20s timeout and a ghost-print guard (a lateopen()after timeout closes without writing — prevents duplicate receipts).Packaging:
serialportadded to webpack externals +packageAfterPruneruntime copies, including its transitivedebug/msdeps —test/package-runtime-externals.test.tsnow loads serialport from the packaged tree (same asusb), which catches missing modules at test time instead of at packaged-app boot.Tests
test:bluetooth-select— single persistent listener invariant, latest-callback-wins, stale replies dropped, sender scoping, close cleanup.test:serial-printer— port filtering/naming, win32 short-circuit, payload validation, write-order, close-on-failure, ghost-print guard.pnpm run test(all 8 suites) +ts:checkgreen on this branch (rebased onto current main).Companion PR
The renderer side (chooser session state machine, scan UX, paired-printers UI, transport routing) lands in wcpos/monorepo — that PR must not merge before this one + the submodule pointer bump.