7.5 KiB
7.5 KiB
Agent Guide
This document orients automation agents and contributors to the mp3-com-meta-browser project. The app is a static, single-page experience for browsing a large mp3.com metadata dataset entirely in the browser.
Mission
- Deliver a fast, predictable search and browse experience over the bundled metadata database.
- Keep the implementation lightweight: no server-side code, no build system, minimal dependencies.
- Preserve accessibility, keyboard navigation, and responsive layout from mobile through desktop.
Non-Goals
- Hosting or streaming audio files.
- Mutating the SQLite database (it's read-only at runtime).
- Introducing new frameworks, bundlers, or complex build steps.
Runtime & Architecture
index.htmlis the only HTML page and contains<template>definitions for base views (tpl-*) and overlay dialogs.script.jsbootstraps the app, loads the WASM SQLite runtime, manages view transitions viaUX.replace(...), and handles overlays withUX.openOverlay(...)/UX.closeTop().- Bulma (
bulma.min.css) supplies the UI vocabulary; project-specific tweaks live insite.css. - The SQLite database (
assets/mp3com-meta.sqlite) is fetched lazily using the HTTP virtual file system so only required pages are read. sql.js(bundledsql-wasm.js/sql-wasm.wasm) provides SQLite + FTS5 inside the browser.
Key Assets
index.html– SPA shell, templates, base structure.script.js– Application state, data layer, helpers, and view constructors.site.css– Minimal overrides, transitions, and utility classes.assets/mp3com-meta.sqlite– Read-only metadata database.bulma.min.css– Upstream Bulma build; keep pristine.
Data Access Notes
- Expect to run entirely client-side; the database is opened with read-only mode via
sql.js. - Always page results with
LIMIT ? OFFSET ?; avoidSELECT *unless fetching a single record by ID. - Prefer prepared statements or cached query strings when querying repeatedly.
- Reserve FTS (
fts_tracks) for the free-text Track Search overlay; browse views should stick to indexed base tables to keep fan-out predictable. - HTTP servers used in development or deployment must send
Accept-Ranges: bytesso the VFS can issue range requests.
Database Schema
Use the current schema when writing queries or documentation:
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);
site_stats stores pre-computed metrics that power the stats dashboard. The FTS data tables are SQLite internals; do not query them directly.
UI/UX Conventions
- Stick to semantic HTML with Bulma classes; avoid inline styles.
- Maintain clear focus states and keyboard navigation.
/focuses search,Esccloses the active overlay, and list views support arrow + Enter activation. - Use polite
aria-liveregions for async loading states (seecreateAsyncListState). - Keep DOM renders incremental—do not preload entire datasets or render long tables without pagination.
Shared Utilities (already implemented in script.js)
createTableRenderer– Safely renders tabular data with built-in HTML escaping.createPagination– Standard pagination controls with page size selector.Keyboardhelper – Normalizes Enter/Esc handling for list rows and overlays.createAsyncListState– Manages loading, error, and empty states for async lists.prepareForView– Wrapsdb.prepareto attach view/label metadata for logging.normalizePaginationState/clampPaginationToTotal– Normalizes and clamps pagination inputs while emitting DEBUG telemetry.sqlValue,sqlLike,sqlIdentifier, and thesqltemplate tag – central helpers for manual SQL construction; always use these when interpolating dynamic values.
Debugging & Logging
- Runtime diagnostics are gated behind a localStorage flag. Enable with
localStorage.setItem('mp3com.debug', 'true')(or'false'/removeItemto disable) before reloading the app. - When DEBUG is on, every SQLite statement logs
Query begin/Query endentries (with view, SQL, params, row count, and duration) and captures detailed error payloads before rethrowing. - Pagination helpers emit
[Pagination]logs whenever raw inputs are normalized or clamped (includingclampedToTotalflags when high page numbers are corrected after a count query). - Use
prepareForView(db, VIEW_NAMES.someView, sql, label)so statement metadata matches the originating view; this keeps console traces actionable.
View Status
- Navigation hub (
tpl-nav,createNavView). - Search (
tpl-search). - Browse Artists (
tpl-browse-artists). - Browse Albums (
tpl-browse-albums). - Browse Years (
tpl-browse-years). - Browse Genres (
tpl-browse-genres). - Stats (
tpl-stats). - Artist overlay (
tpl-artist). - Album overlay (
tpl-album). - Track overlay (
tpl-track). - Filters overlay (
tpl-filters). - Keyboard shortcuts overlay (
tpl-keyboard-shortcuts). - About / help overlay (
tpl-about). - Error overlay (
tpl-error).
Implementation Guardrails
- Keep JavaScript modular inside
script.js; annotate non-obvious sections with short explanatory comments when necessary. - Reuse existing helpers before adding new ones.
- Store new assets under
assets/and prefer lazy loading. - Do not modify
bulma.min.css; override insite.cssif required. - Maintain ASCII-only sources unless a file already contains UTF-8 text that requires preservation.
QA Checklist Before Delivery
- Serve the site via a local static server and load
http://localhost:8000/. - Confirm the console is clean (no errors or unhandled promise rejections).
- Verify keyboard navigation (Tab, arrow keys, Enter, Esc) across base views and overlays.
- Exercise search and pagination to ensure queries remain performant (< ~300 ms after warm-up).
- Validate layout on both narrow and wide viewports.
Stay within these constraints to keep the project fast, accessible, and easy to host.