From c7b652bba4ba7b53e23199da34e06168b4e0b05e Mon Sep 17 00:00:00 2001 From: Alexander Bocken Date: Sun, 5 Apr 2026 12:35:38 +0200 Subject: [PATCH] fix: prefer native BarcodeDetector, fall back to WASM ponyfill Native BarcodeDetector works in Chrome/Android WebView over HTTPS. Only load the ZXing WASM ponyfill when native API is unavailable or doesn't support the needed formats. --- src/lib/components/fitness/FoodSearch.svelte | 54 ++++++++++++-------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/src/lib/components/fitness/FoodSearch.svelte b/src/lib/components/fitness/FoodSearch.svelte index 1dce6ba..5bc15db 100644 --- a/src/lib/components/fitness/FoodSearch.svelte +++ b/src/lib/components/fitness/FoodSearch.svelte @@ -209,30 +209,40 @@ await videoEl.play(); scanDebug += ` | video: ${videoEl.videoWidth}x${videoEl.videoHeight}`; - // Import barcode-detector ponyfill with self-hosted WASM - scanDebug += ' | importing detector…'; - let BarcodeDetector; + // Use native BarcodeDetector if available, else ponyfill with self-hosted WASM + scanDebug += ' | loading detector…'; + let detector; + const formats = ['ean_13', 'ean_8', 'upc_a', 'upc_e', 'code_128']; try { - const mod = await import('barcode-detector/ponyfill'); - BarcodeDetector = mod.BarcodeDetector; - - // Point ZXing WASM to our self-hosted copy in /static - mod.prepareZXingModule({ - overrides: { - locateFile: (path, prefix) => { - if (path.endsWith('.wasm')) return '/fitness/zxing_reader.wasm'; - return prefix + path; - }, - }, - }); - scanDebug += ' OK'; - } catch (importErr) { - scanDebug = `IMPORT ERROR: ${importErr?.message ?? importErr}`; - stopScan(); - return; + if ('BarcodeDetector' in globalThis) { + const supported = await globalThis.BarcodeDetector.getSupportedFormats(); + if (supported.includes('ean_13')) { + detector = new globalThis.BarcodeDetector({ formats }); + scanDebug += ' native'; + } + } + } catch { + // native not usable, fall through to ponyfill + } + if (!detector) { + try { + const mod = await import('barcode-detector/ponyfill'); + mod.prepareZXingModule({ + overrides: { + locateFile: (path, prefix) => { + if (path.endsWith('.wasm')) return '/fitness/zxing_reader.wasm'; + return prefix + path; + }, + }, + }); + detector = new mod.BarcodeDetector({ formats }); + scanDebug += ' ponyfill'; + } catch (importErr) { + scanDebug = `IMPORT ERROR: ${importErr?.message ?? importErr}`; + stopScan(); + return; + } } - - const detector = new BarcodeDetector({ formats: ['ean_13', 'ean_8', 'upc_a', 'upc_e', 'code_128'] }); scanDebug += ' | detector created'; let scanCount = 0;