From cc8fcdbd69001974c53e6b3396cd833e258073ea Mon Sep 17 00:00:00 2001 From: mARTin-B78 Date: Fri, 4 Sep 2026 09:15:41 +0200 Subject: [PATCH] refactor: share frontend module manifest --- CHANGELOG.md | 2 ++ TODO.md | 3 ++- VERSION | 2 +- scripts/minify.mjs | 8 ++------ static/loader.js | 38 ++++++++++--------------------------- static/module-manifest.json | 6 ++++++ 6 files changed, 23 insertions(+), 36 deletions(-) create mode 100644 static/module-manifest.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 93d6361..0efab46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -80,6 +80,8 @@ Follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) · versioned wi missing, stale, changed after profile edits, or explicitly marked inconsistent—even when the prompt version is current. - **Visual Pair Audit.** Added a read-only character-library review endpoint that detects incomplete pairs, reused or identical profile/reference assets, legacy metadata, changed appearance fields, and explicitly inconsistent pairs. +- **Shared Frontend Module Manifest.** The fallback loader and production bundler now consume the same module manifest, + preventing the two loading paths from drifting as the frontend is split further. - **Preview Blob Lifecycle.** Character-library and Rehearser local voice previews now revoke replaced or completed object URLs, reducing retained browser memory during repeated auditioning. - **Character Library Smoke Coverage.** Added deterministic browser coverage for opening Characters / Cast, profile diff --git a/TODO.md b/TODO.md index 3100486..8af9f8b 100644 --- a/TODO.md +++ b/TODO.md @@ -100,7 +100,8 @@ the first block before investing in architecture or polish. - [ ] Split `audiobook.js`, `rehearser.js`, and `style.css` by responsibility. - [ ] Replace broad globals with namespaces such as `window.TTVC.audiobook`. -- [ ] Generate `loader.js` and `scripts/minify.mjs` from one module manifest. +- [x] Generate the feature-module list for `loader.js` and `scripts/minify.mjs` from one shared manifest; + larger responsibility splits remain. - [ ] Add linting and duplicate-function checks. - [ ] Extract Rehearser voice matching and voice design. - [ ] Extract Audiobook parsing and casting. diff --git a/VERSION b/VERSION index 2a0ba77..da9594f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.22.4 +1.22.5 diff --git a/scripts/minify.mjs b/scripts/minify.mjs index 04d696d..239f801 100644 --- a/scripts/minify.mjs +++ b/scripts/minify.mjs @@ -19,12 +19,8 @@ const outDir = join(root, 'static', 'dist'); mkdirSync(outDir, { recursive: true }); // Must match loader.js batch C order exactly. -const MAIN = [ - 'voice-picker', 'benchmark-voice-picker', 'voice-inspector', 'seed-finder', 'voice-sources', 'fishaudio-browser', - 'integrations', 'routing', 'voice-clone', 'voice-library', 'tts-preview', - 'generation', 'benchmark', 'stt', 'rehearser-parse', 'rehearser', 'reader', 'audiobook', 'audiobook/network', 'character-sheets', - 'characters-library', 'sillytavern', 'library', 'character-columns', 'library-characters', 'studio', -].map(n => join(jsDir, n + '.js')); +const MODULES = JSON.parse(readFileSync(join(root, 'static', 'module-manifest.json'), 'utf8')); +const MAIN = MODULES.map(n => join(jsDir, n + '.js')); const source = MAIN.map(f => `\n/* ==== ${f.split('/').pop()} ==== */\n` + readFileSync(f, 'utf8')).join('\n'); diff --git a/static/loader.js b/static/loader.js index c48db3e..671001f 100644 --- a/static/loader.js +++ b/static/loader.js @@ -126,34 +126,16 @@ // C — feature modules: always try the bundle first (one request instead of 23). // Falls back to individual files if the bundle is missing or fails to load. - var _featureFiles = [ - '/static/js/voice-picker.js', - '/static/js/benchmark-voice-picker.js', - '/static/js/voice-inspector.js', - '/static/js/seed-finder.js', - '/static/js/voice-sources.js', - '/static/js/fishaudio-browser.js', - '/static/js/integrations.js', - '/static/js/routing.js', - '/static/js/voice-clone.js', - '/static/js/voice-library.js', - '/static/js/tts-preview.js', - '/static/js/generation.js', - '/static/js/benchmark.js', - '/static/js/stt.js', - '/static/js/rehearser-parse.js', - '/static/js/rehearser.js', - '/static/js/reader.js', - '/static/js/audiobook.js', - '/static/js/audiobook/network.js', - '/static/js/character-sheets.js', - '/static/js/characters-library.js', - '/static/js/sillytavern.js', - '/static/js/library.js', - '/static/js/character-columns.js', - '/static/js/library-characters.js', - '/static/js/studio.js', - ]; + var _featureFiles = []; + try { + var _manifestResponse = await fetch('/static/module-manifest.json?v=' + _appVersion, { cache: 'no-store' }); + if (!_manifestResponse.ok) throw new Error('module manifest ' + _manifestResponse.status); + var _manifest = await _manifestResponse.json(); + if (!Array.isArray(_manifest) || !_manifest.length) throw new Error('empty module manifest'); + _featureFiles = _manifest.map(function (name) { return '/static/js/' + name + '.js'; }); + } catch (_) { + console.error('Unable to load the feature module manifest'); + } var _bundleOk = false; try { await _load('/static/dist/main.min.js'); _bundleOk = true; } catch (_) { _bundleOk = false; } diff --git a/static/module-manifest.json b/static/module-manifest.json new file mode 100644 index 0000000..2d84f4a --- /dev/null +++ b/static/module-manifest.json @@ -0,0 +1,6 @@ +[ + "voice-picker", "benchmark-voice-picker", "voice-inspector", "seed-finder", "voice-sources", "fishaudio-browser", + "integrations", "routing", "voice-clone", "voice-library", "tts-preview", "generation", "benchmark", "stt", + "rehearser-parse", "rehearser", "reader", "audiobook", "audiobook/network", "character-sheets", + "characters-library", "sillytavern", "library", "character-columns", "library-characters", "studio" +]