81 lines
2.3 KiB
TypeScript
81 lines
2.3 KiB
TypeScript
import {
|
|
readFileSync,
|
|
writeFileSync,
|
|
existsSync,
|
|
readdirSync,
|
|
copyFileSync,
|
|
rmSync,
|
|
unlinkSync
|
|
} from 'fs';
|
|
import { resolve } from 'path';
|
|
import type { Plugin } from 'vite';
|
|
import * as fflate from 'fflate';
|
|
|
|
const GUIDE_FOR_FRONTEND = `
|
|
<!--
|
|
This is a static build of the frontend.
|
|
It is automatically generated by the build process.
|
|
Do not edit this file directly.
|
|
To make changes, refer to the "Web UI" section in the README.
|
|
-->
|
|
`.trim();
|
|
|
|
const OUTPUT_DIR = process.env.LLAMA_UI_OUT_DIR ?? './dist';
|
|
const MAX_BUNDLE_SIZE = 3 * 1024 * 1024;
|
|
|
|
export function llamaCppBuildPlugin() {
|
|
return {
|
|
name: 'llamacpp:build',
|
|
apply: 'build' as const,
|
|
closeBundle() {
|
|
// Ensure the SvelteKit adapter has finished writing to ../public
|
|
setTimeout(() => {
|
|
try {
|
|
const indexPath = resolve('../public_llamacpp/index_llamacpp.html');
|
|
const gzipPath = resolve('../public_llamacpp/index_llamacpp.html.gz');
|
|
|
|
if (!existsSync(indexPath)) {
|
|
return;
|
|
}
|
|
|
|
let content = readFileSync(indexPath, 'utf-8');
|
|
|
|
const faviconPath = resolve('static/favicon.svg');
|
|
if (existsSync(faviconPath)) {
|
|
const faviconContent = readFileSync(faviconPath, 'utf-8');
|
|
const faviconBase64 = Buffer.from(faviconContent).toString('base64');
|
|
const faviconDataUrl = `data:image/svg+xml;base64,${faviconBase64}`;
|
|
|
|
content = content.replace(/href="[^"]*favicon\.svg"/g, `href="${faviconDataUrl}"`);
|
|
|
|
console.log('✓ Inlined favicon.svg as base64 data URL');
|
|
}
|
|
|
|
content = content.replace(/\r/g, '');
|
|
content = GUIDE_FOR_FRONTEND + '\n' + content;
|
|
|
|
const compressed = fflate.gzipSync(Buffer.from(content, 'utf-8'), { level: 9 });
|
|
|
|
compressed[0x4] = 0;
|
|
compressed[0x5] = 0;
|
|
compressed[0x6] = 0;
|
|
compressed[0x7] = 0;
|
|
compressed[0x9] = 0;
|
|
|
|
if (compressed.byteLength > MAX_BUNDLE_SIZE) {
|
|
throw new Error(
|
|
`Bundle size is too large (${Math.ceil(compressed.byteLength / 1024)} KB).\n` +
|
|
`Please reduce the size of the frontend or increase MAX_BUNDLE_SIZE in vite.config.ts.\n`
|
|
);
|
|
}
|
|
|
|
writeFileSync(gzipPath, compressed);
|
|
console.log('✓ Created index_llamacpp.html.gz');
|
|
} catch (error) {
|
|
console.error('Failed to create gzip file:', error);
|
|
}
|
|
}, 100);
|
|
}
|
|
};
|
|
}
|