mirror of
https://github.com/ggml-org/llama.cpp.git
synced 2025-11-07 09:57:00 +00:00
* webui : Revised LaTeX formula recognition * webui : Further examples containg amounts * webui : vitest for maskInlineLaTeX * webui: Moved preprocessLaTeX to lib/utils * webui: LaTeX in table-cells * chore: update webui build output (use theirs) * webui: backslash in LaTeX-preprocessing * chore: update webui build output * webui: look-behind backslash-check * chore: update webui build output * Apply suggestions from code review Code maintenance (variable names, code formatting, string handling) Co-authored-by: Aleksander Grygier <aleksander.grygier@gmail.com> * webui: Moved constants to lib/constants. * webui: package woff2 inside base64 data * webui: LaTeX-line-break in display formula * chore: update webui build output * webui: Bugfix (font embedding) * webui: Bugfix (font embedding) * webui: vite embeds assets * webui: don't suppress 404 (fonts) * refactor: KaTeX integration with SCSS Moves KaTeX styling to SCSS for better customization and font embedding. This change includes: - Adding `sass` as a dev dependency. - Introducing a custom SCSS file to override KaTeX variables and disable TTF/WOFF fonts, relying solely on WOFF2 for embedding. - Adjusting the Vite configuration to resolve `katex-fonts` alias and inject SCSS variables. * fix: LaTeX processing within blockquotes * webui: update webui build output --------- Co-authored-by: Aleksander Grygier <aleksander.grygier@gmail.com>
169 lines
4.3 KiB
TypeScript
169 lines
4.3 KiB
TypeScript
import tailwindcss from '@tailwindcss/vite';
|
|
import { sveltekit } from '@sveltejs/kit/vite';
|
|
import * as fflate from 'fflate';
|
|
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
|
import { resolve } from 'path';
|
|
import { defineConfig } from 'vite';
|
|
import devtoolsJson from 'vite-plugin-devtools-json';
|
|
import { storybookTest } from '@storybook/addon-vitest/vitest-plugin';
|
|
|
|
const GUIDE_FOR_FRONTEND = `
|
|
<!--
|
|
This is a single file 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 MAX_BUNDLE_SIZE = 2 * 1024 * 1024;
|
|
|
|
/**
|
|
* the maximum size of an embedded asset in bytes,
|
|
* e.g. maximum size of embedded font (see node_modules/katex/dist/fonts/*.woff2)
|
|
*/
|
|
const MAX_ASSET_SIZE = 32000;
|
|
|
|
/** public/index.html.gz minified flag */
|
|
const ENABLE_JS_MINIFICATION = true;
|
|
|
|
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/index.html');
|
|
const gzipPath = resolve('../public/index.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.html.gz');
|
|
} catch (error) {
|
|
console.error('Failed to create gzip file:', error);
|
|
}
|
|
}, 100);
|
|
}
|
|
};
|
|
}
|
|
|
|
export default defineConfig({
|
|
resolve: {
|
|
alias: {
|
|
'katex-fonts': resolve('node_modules/katex/dist/fonts')
|
|
}
|
|
},
|
|
build: {
|
|
assetsInlineLimit: MAX_ASSET_SIZE,
|
|
chunkSizeWarningLimit: 3072,
|
|
minify: ENABLE_JS_MINIFICATION
|
|
},
|
|
css: {
|
|
preprocessorOptions: {
|
|
scss: {
|
|
additionalData: `
|
|
$use-woff2: true;
|
|
$use-woff: false;
|
|
$use-ttf: false;
|
|
`
|
|
}
|
|
}
|
|
},
|
|
plugins: [tailwindcss(), sveltekit(), devtoolsJson(), llamaCppBuildPlugin()],
|
|
test: {
|
|
projects: [
|
|
{
|
|
extends: './vite.config.ts',
|
|
test: {
|
|
name: 'client',
|
|
environment: 'browser',
|
|
browser: {
|
|
enabled: true,
|
|
provider: 'playwright',
|
|
instances: [{ browser: 'chromium' }]
|
|
},
|
|
include: ['src/**/*.svelte.{test,spec}.{js,ts}'],
|
|
exclude: ['src/lib/server/**'],
|
|
setupFiles: ['./vitest-setup-client.ts']
|
|
}
|
|
},
|
|
{
|
|
extends: './vite.config.ts',
|
|
test: {
|
|
name: 'server',
|
|
environment: 'node',
|
|
include: ['src/**/*.{test,spec}.{js,ts}'],
|
|
exclude: ['src/**/*.svelte.{test,spec}.{js,ts}']
|
|
}
|
|
},
|
|
{
|
|
extends: './vite.config.ts',
|
|
test: {
|
|
name: 'ui',
|
|
environment: 'browser',
|
|
browser: {
|
|
enabled: true,
|
|
provider: 'playwright',
|
|
instances: [{ browser: 'chromium', headless: true }]
|
|
},
|
|
include: ['src/**/*.stories.{js,ts,svelte}'],
|
|
setupFiles: ['./.storybook/vitest.setup.ts']
|
|
},
|
|
plugins: [
|
|
storybookTest({
|
|
storybookScript: 'pnpm run storybook --no-open'
|
|
})
|
|
]
|
|
}
|
|
]
|
|
},
|
|
|
|
server: {
|
|
proxy: {
|
|
'/v1': 'http://localhost:8080',
|
|
'/props': 'http://localhost:8080',
|
|
'/slots': 'http://localhost:8080'
|
|
},
|
|
headers: {
|
|
'Cross-Origin-Embedder-Policy': 'require-corp',
|
|
'Cross-Origin-Opener-Policy': 'same-origin'
|
|
}
|
|
}
|
|
});
|