tts-voice-creator-clone-and.../scripts/minify.mjs
mARTin-B78 36437478a6 feat: Read Aloud reader, multi-voice audiobook casting, character sheets (v1.7.0)
Read Aloud (new "Vorlesen" tab):
- PDF (real page render + overlay highlight) / TXT reader with live word
  highlighting, voice + speed, per-sentence synthesis-state colours, zoom
  (fit-width/height, two-page, ±), resume, and a server-side book library
  (syncs across devices; per-unit MP3 audio fetched on demand).

Book -> multi-speaker audiobook:
- "Cast as audiobook" attributes dialogue to characters via the LLM
  (guillemet/quote-style aware, turn-taking, recent-context), with a
  deterministic speech-tag fallback. Editable preview, non-blocking live
  casting panel, then auto-saved as a reopenable Script Rehearser play.
- Audiobook export: synthesise every cast line -> one MP3 per chapter.

Character sheets:
- LLM-extracted, self-filling RPG-style sheets (with page+quote sources)
  in both Read Aloud and the Rehearser.

Also: MP3 storage + per-page/sentence export, voice-library "Precompute
embeddings" pre-warm, German "Vorlesen" i18n + flag language toggle,
large-PDF performance (lazy raster, buffer/canvas eviction, yielded parse),
and the Seed Finder changelog entry.

New: routes/reader.py, POST /api/attribute-dialogue, POST /api/character-sheets,
static/js/{reader,audiobook,character-sheets}.js, static/sections/s-reader.html.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 15:08:46 +02:00

43 lines
1.9 KiB
JavaScript

// Build an opt-in production bundle WITHOUT changing runtime semantics.
//
// The feature modules share a single global scope and are executed in a fixed order
// (see loader.js). We therefore CONCATENATE them in that exact order into one file and
// minify whitespace/syntax only — identifiers are kept, because inline HTML handlers
// (onclick="navTo(...)") and cross-file references rely on global names.
//
// Run: npm run minify → static/dist/main.min.js
// Enable at runtime with window.APP_USE_BUNDLE=true (or ?bundle=1). Default stays
// per-file so editing static/js/* is live without a rebuild.
import { transform } from 'esbuild';
import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
const root = join(dirname(fileURLToPath(import.meta.url)), '..');
const jsDir = join(root, 'static', 'js');
const outDir = join(root, 'static', 'dist');
mkdirSync(outDir, { recursive: true });
// Must match loader.js batch C order exactly.
const MAIN = [
'voice-picker', 'voice-inspector', 'voice-sources', 'fishaudio-browser',
'integrations', 'routing', 'voice-clone', 'voice-library', 'tts-preview',
'benchmark', 'stt', 'rehearser-parse', 'rehearser', 'reader', 'audiobook', 'character-sheets',
].map(n => join(jsDir, n + '.js'));
const source = MAIN.map(f => `\n/* ==== ${f.split('/').pop()} ==== */\n` + readFileSync(f, 'utf8')).join('\n');
const { code } = await transform(source, {
loader: 'js',
minify: false,
minifyWhitespace: true,
minifySyntax: true,
minifyIdentifiers: false, // keep global names referenced by HTML & other files
legalComments: 'none',
target: ['es2019', 'safari14'],
});
const out = join(outDir, 'main.min.js');
writeFileSync(out, code);
console.log(`Bundled ${MAIN.length} modules → static/dist/main.min.js (${(code.length / 1024).toFixed(0)} KB)`);