From dc05817267abb52d3e3bf85c7c28863a0b0a579c Mon Sep 17 00:00:00 2001 From: Triple7 Date: Mon, 4 May 2026 04:10:06 -0700 Subject: [PATCH] Fix metadata parser import resolution for build stability --- src/utils/metadata.js | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/utils/metadata.js b/src/utils/metadata.js index 95e1707..36cb772 100644 --- a/src/utils/metadata.js +++ b/src/utils/metadata.js @@ -1,9 +1,22 @@ -import { parseBlob } from 'music-metadata-browser'; import ID3Writer from 'browser-id3-writer'; const AI_MARKERS = ['ai','generated','suno','udio','boomy','aiva','soundraw','mubert','stable audio','provenance','c2pa','content credentials','watermark','synthetic','elevenlabs']; const MARKER_REGEX_CACHE = new Map(); +let parseBlobLoader = null; + +async function getParseBlob() { + if (parseBlobLoader) return parseBlobLoader; + parseBlobLoader = import('music-metadata-browser').then((mod) => { + const fn = mod?.parseBlob || mod?.default?.parseBlob; + if (typeof fn !== 'function') { + throw new Error('music-metadata-browser parseBlob export not found'); + } + return fn; + }); + return parseBlobLoader; +} + function escapeRegex(value) { return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } @@ -18,7 +31,7 @@ function markerToRegex(marker) { return regex; } -function collectStrings(metadata) { +function collectStrings(metadata, fileName = '') { const common = metadata?.common || {}; const native = metadata?.native || {}; const values = [common.title,common.artist,common.album,...(common.genre || []),...(common.comment || []),common.encodedby,common.publisher] @@ -31,6 +44,7 @@ function collectStrings(metadata) { if (frame?.value && typeof frame.value === 'object') values.push(JSON.stringify(frame.value)); }); }); + if (fileName) values.push(String(fileName)); return values.join(' | ').toLowerCase(); } @@ -39,12 +53,13 @@ export async function readFileMetadata(file) { let parseError = null; try { + const parseBlob = await getParseBlob(); parsed = await parseBlob(file); } catch (error) { parseError = error; } - const searchable = collectStrings(parsed); + const searchable = collectStrings(parsed, file?.name || ''); const detectedMarkers = AI_MARKERS.filter((marker) => markerToRegex(marker).test(searchable)); return { format: parsed?.format?.container || file.type || 'unknown',