.gitattributes | ||
.gitignore | ||
AGENTS.md | ||
bulma.min.css | ||
db.zip | ||
index.html | ||
LICENSE | ||
README.md | ||
script.js | ||
site.css | ||
sql-wasm.js | ||
sql-wasm.wasm |
mp3-com-meta-browser
mp3-com-meta-browser is a static single-page web app for exploring the salvaged mp3.com metadata catalog. All queries run entirely in the browser against a read-only SQLite database compiled to WebAssembly, so the site can be hosted on any static file server.
Highlights
- Client-side full-text search (FTS5) powers the dedicated track search overlay.
- Browse views query indexed base tables directly for predictable pagination (no FTS fan-out).
- Responsive Bulma-based UI with dedicated views for search, browse (artists, albums, years, genres), and dataset stats.
- Overlay detail panels for artists, albums, and tracks with keyboard navigation support.
- Zero server dependencies beyond serving static assets with HTTP range support.
Tech Stack
- Bulma (
bulma.min.css
) for layout and components. - Vanilla JavaScript in
script.js
for SPA state management, view controllers, and data access helpers. sql.js
WASM build (sql-wasm.js
/sql-wasm.wasm
) to run SQLite with FTS5 support in the browser.- Local styling refinements in
site.css
. - Metadata database delivered as
/assets/mp3com-meta.sqlite
.
Directory Layout
/
├─ index.html # Single-page app shell and HTML templates
├─ bulma.min.css # Bundled Bulma CSS (do not modify upstream file)
├─ site.css # Local overrides and micro-utilities
├─ script.js # Application logic, helpers, and view controllers
├─ README.md # Project overview (this file)
├─ AGENTS.md # Orientation and guardrails for automation agents
└─ assets/
└─ mp3com-meta.sqlite # Read-only metadata database
Add future static assets (icons, fonts, etc.) under assets/
.
Running Locally
- Start a static file server from the repository root. Examples:
python3 -m http.server 8000
npx http-server -p 8000
- Ensure the server sends
Accept-Ranges: bytes
for/assets/mp3com-meta.sqlite
so the WASM virtual file system can page data on demand. - Visit
http://localhost:8000/
in a modern browser. - Open the developer console to confirm there are no runtime errors.
Using the App
- Search: Free-text search with 250 ms debounce. Toggle between relevance and alphabetical sorting. Keyboard:
/
focuses search,Enter
activates the highlighted row. - Browse Artists / Albums / Years / Genres: Paginated listings with quick filters backed by indexed table queries (
artists
,albums
,tracks
). Selecting an entry opens the corresponding overlay. - Stats: Summary cards pull from pre-computed counters in
site_stats
and link into browse views with preset filters. - Overlays: Artist, album, and track overlays show detailed metadata.
Esc
closes the top overlay and focus returns to the invoker.
Only the Track Search overlay issues FTS queries. Browse views stay on indexed base tables so pagination remains predictable and light on resources.
Keyboard & Accessibility Notes
- Global shortcuts:
/
for search,Esc
to close overlays. - Lists expose arrow navigation with
Enter
activation when focused. - Focus indicators remain visible; async list regions use polite
aria-live
messages. - Ensure new UI follows Bulma semantics and pairs labels with inputs.
Database Schema
The bundled database enforces foreign keys and ships with an FTS5 index over key text fields. The current schema is:
PRAGMA foreign_keys=ON;
CREATE TABLE artists(
id INTEGER PRIMARY KEY,
name TEXT NOT NULL COLLATE NOCASE UNIQUE
);
CREATE TABLE albums(
id INTEGER PRIMARY KEY,
artist_id INTEGER NOT NULL REFERENCES artists(id),
title TEXT COLLATE NOCASE,
year INTEGER,
UNIQUE(artist_id, title, year)
);
CREATE TABLE tracks(
id INTEGER PRIMARY KEY,
artist_id INTEGER NOT NULL REFERENCES artists(id),
album_id INTEGER REFERENCES albums(id),
title TEXT NOT NULL COLLATE NOCASE,
track_no INTEGER,
year INTEGER,
genre TEXT,
duration_sec INTEGER,
bitrate_kbps INTEGER,
samplerate_hz INTEGER,
channels INTEGER,
filesize_bytes INTEGER,
sha1 TEXT,
relpath TEXT NOT NULL
);
CREATE TABLE site_stats (
name TEXT PRIMARY KEY,
value TEXT NOT NULL
);
CREATE VIRTUAL TABLE fts_tracks USING fts5(
title,
artist,
album,
genre,
content='tracks',
content_rowid='id',
tokenize='unicode61 remove_diacritics 2',
prefix='2 3 4'
);
CREATE TABLE 'fts_tracks_data'(id INTEGER PRIMARY KEY, block BLOB);
CREATE TABLE 'fts_tracks_idx'(segid, term, pgno, PRIMARY KEY(segid, term)) WITHOUT ROWID;
CREATE TABLE 'fts_tracks_docsize'(id INTEGER PRIMARY KEY, sz BLOB);
CREATE TABLE 'fts_tracks_config'(k PRIMARY KEY, v) WITHOUT ROWID;
CREATE INDEX idx_tracks_artist_id ON tracks(artist_id);
CREATE INDEX idx_tracks_album_id ON tracks(album_id);
CREATE INDEX idx_tracks_year ON tracks(year);
CREATE INDEX idx_tracks_genre ON tracks(genre);
CREATE INDEX idx_artists_name ON artists(name COLLATE NOCASE);
CREATE INDEX idx_artists_name_nocase ON artists(name COLLATE NOCASE);
The fts_tracks_*
tables are managed by SQLite to back the FTS5 virtual table. site_stats
stores pre-computed counters that power the stats view. The application issues read-only queries and never mutates the database.
Development Notes
- Keep the app framework-free; do not introduce bundlers or additional dependencies without discussion.
- Reuse HTML templates in
index.html
through theinstantiateTemplate
helper instead of building large DOM fragments manually. - Paginate every query (
LIMIT ? OFFSET ?
) and prefer streaming or incremental rendering for large result sets. - Consolidate shared UI logic (pagination, keyboard handlers, async states) in
script.js
utilities. - Restrict new CSS to scoped utility classes in
site.css
; otherwise rely on Bulma components. - Before submitting changes, verify there are no console warnings, layout adapts from mobile to desktop, and keyboard navigation continues to work.
Debug Instrumentation
- Enable verbose query diagnostics by setting
localStorage.setItem('mp3com.debug', 'true')
and reloading the app (clear the key or set it to'false'
to disable). - With DEBUG on, every SQLite statement logs
Query begin
/Query end
entries that include the originating view, optional label, normalized SQL text, bound parameters, row counts, and execution duration. - Any statement failure logs
[SQLite error]
details (SQL, params, phase, message, stack) before the exception propagates, making it easier to correlate with UI regressions. - Pagination helpers emit
[Pagination]
traces whenever user inputs are normalized or clamped (including high-page corrections after a total count comes back smaller than expected). - Use the
prepareForView(db, VIEW_NAMES.someView, sql, label)
helper when preparing new statements so that console output remains aligned with the feature area generating the query.
License
Add licensing information here when available.