/**
* Inline every module into one self-contained HTML file, so the whole tool is a
* single document that opens straight from the desktop with no install, no
* server and no internet.
*/
import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
const here = dirname(fileURLToPath(import.meta.url));
const root = join(here, '..');
// Dependency order, leaves first.
const MODULES = [
'src/fonts.js',
'src/codec/bitfont.mjs',
'src/codec/td5.mjs',
'src/codec/tp5.mjs',
'src/codec/sheet.mjs',
'app/main.mjs',
];
function strip(src, name) {
const out = src
// drop the import lines; every symbol ends up in one shared scope
.replace(/^\s*import\s+[^;]*?from\s*['"][^'"]+['"];?\s*$/gm, '')
// `export const X` -> `const X`, `export function f` -> `function f`
.replace(/^export\s+(const|let|var|function|class|async)\b/gm, '$1')
// bare re-export statements, if any ever appear
.replace(/^export\s*\{[^}]*\};?\s*$/gm, '');
if (/^\s*(import|export)\b/m.test(out)) {
throw new Error(`${name}: an import/export slipped through the bundler`);
}
return `\n// ===== ${name} =====\n${out.trim()}\n`;
}
const code = MODULES.map((m) => strip(readFileSync(join(root, m), 'utf8'), m)).join('\n');
const html = readFileSync(join(root, 'app/index.html'), 'utf8');
if (!html.includes('')) {
throw new Error('index.html no longer has the expected script tag');
}
const banner = `
`;
const bundled = banner + html.replace(
'',
``
);
mkdirSync(join(root, 'dist'), { recursive: true });
const outPath = join(root, 'dist/DestoGod.html');
writeFileSync(outPath, bundled);
console.log(`wrote dist/DestoGod.html (${(bundled.length / 1024).toFixed(0)} KB, ${MODULES.length} modules inlined)`);