server: (webui) no more gzip compression (#21073)
* webui: no more gzip * try changing a small line * Revert "try changing a small line" This reverts commit 0d7a3531593d87b724d404c8727a96becab3ab07. * fix lint * fix test * rebuild * split into html/css/js * lint * chore: update webui build output * chore: Update git hooks script * server: update webui build output * chore: Update pre-commit hook * refactor: Cleanup --------- Co-authored-by: Aleksander Grygier <aleksander.grygier@gmail.com>
This commit is contained in:
parent
624733d631
commit
4a00bbfed6
18 changed files with 608 additions and 209 deletions
|
|
@ -21,14 +21,6 @@ indent_style = tab
|
||||||
[prompts/*.txt]
|
[prompts/*.txt]
|
||||||
insert_final_newline = unset
|
insert_final_newline = unset
|
||||||
|
|
||||||
[tools/server/public/*]
|
|
||||||
indent_size = 2
|
|
||||||
|
|
||||||
[tools/server/public/deps_*]
|
|
||||||
trim_trailing_whitespace = unset
|
|
||||||
indent_style = unset
|
|
||||||
indent_size = unset
|
|
||||||
|
|
||||||
[tools/server/deps_*]
|
[tools/server/deps_*]
|
||||||
trim_trailing_whitespace = unset
|
trim_trailing_whitespace = unset
|
||||||
indent_style = unset
|
indent_style = unset
|
||||||
|
|
@ -61,6 +53,14 @@ charset = unset
|
||||||
trim_trailing_whitespace = unset
|
trim_trailing_whitespace = unset
|
||||||
insert_final_newline = unset
|
insert_final_newline = unset
|
||||||
|
|
||||||
|
[tools/server/public/**]
|
||||||
|
indent_style = unset
|
||||||
|
indent_size = unset
|
||||||
|
end_of_line = unset
|
||||||
|
charset = unset
|
||||||
|
trim_trailing_whitespace = unset
|
||||||
|
insert_final_newline = unset
|
||||||
|
|
||||||
[benches/**]
|
[benches/**]
|
||||||
indent_style = unset
|
indent_style = unset
|
||||||
indent_size = unset
|
indent_size = unset
|
||||||
|
|
|
||||||
4
.gitattributes
vendored
Normal file
4
.gitattributes
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
# Treat the generated single-file WebUI build as binary for diff purposes.
|
||||||
|
# Git's pack-file delta compression still works (byte-level), but this prevents
|
||||||
|
# git diff from printing the entire minified file on every change.
|
||||||
|
tools/server/public/index.html -diff
|
||||||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -95,6 +95,8 @@
|
||||||
# Server Web UI temporary files
|
# Server Web UI temporary files
|
||||||
/tools/server/webui/node_modules
|
/tools/server/webui/node_modules
|
||||||
/tools/server/webui/dist
|
/tools/server/webui/dist
|
||||||
|
# we no longer use gz for index.html
|
||||||
|
/tools/server/public/index.html.gz
|
||||||
|
|
||||||
# Python
|
# Python
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,9 @@ option(LLAMA_BUILD_WEBUI "Build the embedded Web UI" ON)
|
||||||
|
|
||||||
if (LLAMA_BUILD_WEBUI)
|
if (LLAMA_BUILD_WEBUI)
|
||||||
set(PUBLIC_ASSETS
|
set(PUBLIC_ASSETS
|
||||||
index.html.gz
|
index.html
|
||||||
|
bundle.js
|
||||||
|
bundle.css
|
||||||
loading.html
|
loading.html
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -259,6 +259,6 @@ npm run test
|
||||||
npm run build
|
npm run build
|
||||||
```
|
```
|
||||||
|
|
||||||
After `public/index.html.gz` has been generated, rebuild `llama-server` as described in the [build](#build) section to include the updated UI.
|
After `public/index.html` has been generated, rebuild `llama-server` as described in the [build](#build) section to include the updated UI.
|
||||||
|
|
||||||
**Note:** The Vite dev server automatically proxies API requests to `http://localhost:8080`. Make sure `llama-server` is running on that port during development.
|
**Note:** The Vite dev server automatically proxies API requests to `http://localhost:8080`. Make sure `llama-server` is running on that port during development.
|
||||||
|
|
|
||||||
1
tools/server/public/bundle.css
Normal file
1
tools/server/public/bundle.css
Normal file
File diff suppressed because one or more lines are too long
469
tools/server/public/bundle.js
Normal file
469
tools/server/public/bundle.js
Normal file
File diff suppressed because one or more lines are too long
34
tools/server/public/index.html
Normal file
34
tools/server/public/index.html
Normal file
File diff suppressed because one or more lines are too long
Binary file not shown.
|
|
@ -10,7 +10,9 @@
|
||||||
|
|
||||||
#ifdef LLAMA_BUILD_WEBUI
|
#ifdef LLAMA_BUILD_WEBUI
|
||||||
// auto generated files (see README.md for details)
|
// auto generated files (see README.md for details)
|
||||||
#include "index.html.gz.hpp"
|
#include "index.html.hpp"
|
||||||
|
#include "bundle.js.hpp"
|
||||||
|
#include "bundle.css.hpp"
|
||||||
#include "loading.html.hpp"
|
#include "loading.html.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -272,16 +274,19 @@ bool server_http_context::init(const common_params & params) {
|
||||||
} else {
|
} else {
|
||||||
#ifdef LLAMA_BUILD_WEBUI
|
#ifdef LLAMA_BUILD_WEBUI
|
||||||
// using embedded static index.html
|
// using embedded static index.html
|
||||||
srv->Get(params.api_prefix + "/", [](const httplib::Request & req, httplib::Response & res) {
|
srv->Get(params.api_prefix + "/", [](const httplib::Request & /*req*/, httplib::Response & res) {
|
||||||
if (req.get_header_value("Accept-Encoding").find("gzip") == std::string::npos) {
|
// COEP and COOP headers, required by pyodide (python interpreter)
|
||||||
res.set_content("Error: gzip is not supported by this browser", "text/plain");
|
res.set_header("Cross-Origin-Embedder-Policy", "require-corp");
|
||||||
} else {
|
res.set_header("Cross-Origin-Opener-Policy", "same-origin");
|
||||||
res.set_header("Content-Encoding", "gzip");
|
res.set_content(reinterpret_cast<const char*>(index_html), index_html_len, "text/html; charset=utf-8");
|
||||||
// COEP and COOP headers, required by pyodide (python interpreter)
|
return false;
|
||||||
res.set_header("Cross-Origin-Embedder-Policy", "require-corp");
|
});
|
||||||
res.set_header("Cross-Origin-Opener-Policy", "same-origin");
|
srv->Get(params.api_prefix + "/bundle.js", [](const httplib::Request & /*req*/, httplib::Response & res) {
|
||||||
res.set_content(reinterpret_cast<const char*>(index_html_gz), index_html_gz_len, "text/html; charset=utf-8");
|
res.set_content(reinterpret_cast<const char*>(bundle_js), bundle_js_len, "application/javascript; charset=utf-8");
|
||||||
}
|
return false;
|
||||||
|
});
|
||||||
|
srv->Get(params.api_prefix + "/bundle.css", [](const httplib::Request & /*req*/, httplib::Response & res) {
|
||||||
|
res.set_content(reinterpret_cast<const char*>(bundle_css), bundle_css_len, "text/css; charset=utf-8");
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -188,14 +188,14 @@ The build process:
|
||||||
1. **Vite Build** - Bundles all TypeScript, Svelte, and CSS
|
1. **Vite Build** - Bundles all TypeScript, Svelte, and CSS
|
||||||
2. **Static Adapter** - Outputs to `../public` (llama-server's static file directory)
|
2. **Static Adapter** - Outputs to `../public` (llama-server's static file directory)
|
||||||
3. **Post-Build Script** - Cleans up intermediate files
|
3. **Post-Build Script** - Cleans up intermediate files
|
||||||
4. **Custom Plugin** - Creates `index.html.gz` with:
|
4. **Custom Plugin** - Creates `index.html` with:
|
||||||
- Inlined favicon as base64
|
- Inlined favicon as base64
|
||||||
- GZIP compression (level 9)
|
- GZIP compression (level 9)
|
||||||
- Deterministic output (zeroed timestamps)
|
- Deterministic output (zeroed timestamps)
|
||||||
|
|
||||||
```text
|
```text
|
||||||
tools/server/webui/ → build → tools/server/public/
|
tools/server/webui/ → build → tools/server/public/
|
||||||
├── src/ ├── index.html.gz (served by llama-server)
|
├── src/ ├── index.html (served by llama-server)
|
||||||
├── static/ └── (favicon inlined)
|
├── static/ └── (favicon inlined)
|
||||||
└── ...
|
└── ...
|
||||||
```
|
```
|
||||||
|
|
@ -219,7 +219,7 @@ output: {
|
||||||
|
|
||||||
The WebUI is embedded directly into the llama-server binary:
|
The WebUI is embedded directly into the llama-server binary:
|
||||||
|
|
||||||
1. `npm run build` outputs `index.html.gz` to `tools/server/public/`
|
1. `npm run build` outputs `index.html` to `tools/server/public/`
|
||||||
2. llama-server compiles this into the binary at build time
|
2. llama-server compiles this into the binary at build time
|
||||||
3. When accessing `/`, llama-server serves the gzipped HTML
|
3. When accessing `/`, llama-server serves the gzipped HTML
|
||||||
4. All assets are inlined (CSS, JS, fonts, favicon)
|
4. All assets are inlined (CSS, JS, fonts, favicon)
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,6 @@
|
||||||
"eslint-config-prettier": "^10.0.1",
|
"eslint-config-prettier": "^10.0.1",
|
||||||
"eslint-plugin-storybook": "^10.2.4",
|
"eslint-plugin-storybook": "^10.2.4",
|
||||||
"eslint-plugin-svelte": "^3.0.0",
|
"eslint-plugin-svelte": "^3.0.0",
|
||||||
"fflate": "^0.8.2",
|
|
||||||
"globals": "^16.0.0",
|
"globals": "^16.0.0",
|
||||||
"http-server": "^14.1.1",
|
"http-server": "^14.1.1",
|
||||||
"mdast": "^3.0.0",
|
"mdast": "^3.0.0",
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,12 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Script to install pre-commit and pre-push hooks for webui
|
# Script to install pre-commit hook for webui
|
||||||
# Pre-commit: formats code and runs checks
|
# Pre-commit: formats, checks, builds, and stages build output
|
||||||
# Pre-push: builds the project, stashes unstaged changes
|
|
||||||
|
|
||||||
REPO_ROOT=$(git rev-parse --show-toplevel)
|
REPO_ROOT=$(git rev-parse --show-toplevel)
|
||||||
PRE_COMMIT_HOOK="$REPO_ROOT/.git/hooks/pre-commit"
|
PRE_COMMIT_HOOK="$REPO_ROOT/.git/hooks/pre-commit"
|
||||||
PRE_PUSH_HOOK="$REPO_ROOT/.git/hooks/pre-push"
|
|
||||||
|
|
||||||
echo "Installing pre-commit and pre-push hooks for webui..."
|
echo "Installing pre-commit hook for webui..."
|
||||||
|
|
||||||
# Create the pre-commit hook
|
# Create the pre-commit hook
|
||||||
cat > "$PRE_COMMIT_HOOK" << 'EOF'
|
cat > "$PRE_COMMIT_HOOK" << 'EOF'
|
||||||
|
|
@ -16,21 +14,19 @@ cat > "$PRE_COMMIT_HOOK" << 'EOF'
|
||||||
|
|
||||||
# Check if there are any changes in the webui directory
|
# Check if there are any changes in the webui directory
|
||||||
if git diff --cached --name-only | grep -q "^tools/server/webui/"; then
|
if git diff --cached --name-only | grep -q "^tools/server/webui/"; then
|
||||||
echo "Formatting and checking webui code..."
|
REPO_ROOT=$(git rev-parse --show-toplevel)
|
||||||
|
cd "$REPO_ROOT/tools/server/webui"
|
||||||
# Change to webui directory and run format
|
|
||||||
cd tools/server/webui
|
# Check if package.json exists
|
||||||
|
|
||||||
# Check if npm is available and package.json exists
|
|
||||||
if [ ! -f "package.json" ]; then
|
if [ ! -f "package.json" ]; then
|
||||||
echo "Error: package.json not found in tools/server/webui"
|
echo "Error: package.json not found in tools/server/webui"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo "Formatting and checking webui code..."
|
||||||
|
|
||||||
# Run the format command
|
# Run the format command
|
||||||
npm run format
|
npm run format
|
||||||
|
|
||||||
# Check if format command succeeded
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
echo "Error: npm run format failed"
|
echo "Error: npm run format failed"
|
||||||
exit 1
|
exit 1
|
||||||
|
|
@ -38,8 +34,6 @@ if git diff --cached --name-only | grep -q "^tools/server/webui/"; then
|
||||||
|
|
||||||
# Run the lint command
|
# Run the lint command
|
||||||
npm run lint
|
npm run lint
|
||||||
|
|
||||||
# Check if lint command succeeded
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
echo "Error: npm run lint failed"
|
echo "Error: npm run lint failed"
|
||||||
exit 1
|
exit 1
|
||||||
|
|
@ -47,156 +41,42 @@ if git diff --cached --name-only | grep -q "^tools/server/webui/"; then
|
||||||
|
|
||||||
# Run the check command
|
# Run the check command
|
||||||
npm run check
|
npm run check
|
||||||
|
|
||||||
# Check if check command succeeded
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
echo "Error: npm run check failed"
|
echo "Error: npm run check failed"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Go back to repo root
|
|
||||||
cd ../../..
|
|
||||||
|
|
||||||
echo "✅ Webui code formatted and checked successfully"
|
echo "✅ Webui code formatted and checked successfully"
|
||||||
fi
|
|
||||||
|
|
||||||
exit 0
|
# Build the webui
|
||||||
EOF
|
echo "Building webui..."
|
||||||
|
npm run build
|
||||||
# Create the pre-push hook
|
if [ $? -ne 0 ]; then
|
||||||
cat > "$PRE_PUSH_HOOK" << 'EOF'
|
echo "❌ npm run build failed"
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Check if there are any webui changes that need building
|
|
||||||
WEBUI_CHANGES=$(git diff --name-only @{push}..HEAD | grep "^tools/server/webui/" || true)
|
|
||||||
|
|
||||||
if [ -n "$WEBUI_CHANGES" ]; then
|
|
||||||
echo "Webui changes detected, checking if build is up-to-date..."
|
|
||||||
|
|
||||||
# Change to webui directory
|
|
||||||
cd tools/server/webui
|
|
||||||
|
|
||||||
# Check if npm is available and package.json exists
|
|
||||||
if [ ! -f "package.json" ]; then
|
|
||||||
echo "Error: package.json not found in tools/server/webui"
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if build output exists and is newer than source files
|
|
||||||
BUILD_FILE="../public/index.html.gz"
|
|
||||||
NEEDS_BUILD=false
|
|
||||||
|
|
||||||
if [ ! -f "$BUILD_FILE" ]; then
|
|
||||||
echo "Build output not found, building..."
|
|
||||||
NEEDS_BUILD=true
|
|
||||||
else
|
|
||||||
# Check if any source files are newer than the build output
|
|
||||||
if find src -newer "$BUILD_FILE" -type f | head -1 | grep -q .; then
|
|
||||||
echo "Source files are newer than build output, rebuilding..."
|
|
||||||
NEEDS_BUILD=true
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$NEEDS_BUILD" = true ]; then
|
|
||||||
echo "Building webui..."
|
|
||||||
|
|
||||||
# Stash any unstaged changes to avoid conflicts during build
|
|
||||||
echo "Checking for unstaged changes..."
|
|
||||||
if ! git diff --quiet || ! git diff --cached --quiet --diff-filter=A; then
|
|
||||||
echo "Stashing unstaged changes..."
|
|
||||||
git stash push --include-untracked -m "Pre-push hook: stashed unstaged changes"
|
|
||||||
STASH_CREATED=$?
|
|
||||||
else
|
|
||||||
echo "No unstaged changes to stash"
|
|
||||||
STASH_CREATED=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Run the build command
|
|
||||||
npm run build
|
|
||||||
|
|
||||||
# Check if build command succeeded
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
echo "Error: npm run build failed"
|
|
||||||
if [ $STASH_CREATED -eq 0 ]; then
|
|
||||||
echo "You can restore your unstaged changes with: git stash pop"
|
|
||||||
fi
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Go back to repo root
|
# Stage the build output alongside the source changes
|
||||||
cd ../../..
|
cd "$REPO_ROOT"
|
||||||
|
git add tools/server/public/
|
||||||
# Check if build output was created/updated
|
|
||||||
if [ -f "tools/server/public/index.html.gz" ]; then
|
echo "✅ Webui built and build output staged"
|
||||||
# Add the build output and commit it
|
|
||||||
git add tools/server/public/index.html.gz
|
|
||||||
if ! git diff --cached --quiet; then
|
|
||||||
echo "Committing updated build output..."
|
|
||||||
git commit -m "chore: update webui build output"
|
|
||||||
echo "✅ Build output committed successfully"
|
|
||||||
else
|
|
||||||
echo "Build output unchanged"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "Error: Build output not found after build"
|
|
||||||
if [ $STASH_CREATED -eq 0 ]; then
|
|
||||||
echo "You can restore your unstaged changes with: git stash pop"
|
|
||||||
fi
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ $STASH_CREATED -eq 0 ]; then
|
|
||||||
echo "✅ Build completed. Your unstaged changes have been stashed."
|
|
||||||
echo "They will be automatically restored after the push."
|
|
||||||
# Create a marker file to indicate stash was created by pre-push hook
|
|
||||||
touch .git/WEBUI_PUSH_STASH_MARKER
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "✅ Build output is up-to-date"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "✅ Webui ready for push"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Create the post-push hook (for restoring stashed changes after push)
|
# Make hook executable
|
||||||
cat > "$REPO_ROOT/.git/hooks/post-push" << 'EOF'
|
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Check if we have a stash marker from the pre-push hook
|
|
||||||
if [ -f .git/WEBUI_PUSH_STASH_MARKER ]; then
|
|
||||||
echo "Restoring your unstaged changes after push..."
|
|
||||||
git stash pop
|
|
||||||
rm -f .git/WEBUI_PUSH_STASH_MARKER
|
|
||||||
echo "✅ Your unstaged changes have been restored."
|
|
||||||
fi
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Make all hooks executable
|
|
||||||
chmod +x "$PRE_COMMIT_HOOK"
|
chmod +x "$PRE_COMMIT_HOOK"
|
||||||
chmod +x "$PRE_PUSH_HOOK"
|
|
||||||
chmod +x "$REPO_ROOT/.git/hooks/post-push"
|
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
echo "✅ Git hooks installed successfully!"
|
echo "✅ Git hook installed successfully!"
|
||||||
echo " Pre-commit: $PRE_COMMIT_HOOK"
|
echo " Pre-commit: $PRE_COMMIT_HOOK"
|
||||||
echo " Pre-push: $PRE_PUSH_HOOK"
|
|
||||||
echo " Post-push: $REPO_ROOT/.git/hooks/post-push"
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "The hooks will automatically:"
|
echo "The hook will automatically:"
|
||||||
echo " • Format and check webui code before commits (pre-commit)"
|
echo " • Format, lint and check webui code before commits"
|
||||||
echo " • Build webui code before pushes (pre-push)"
|
echo " • Build webui and stage tools/server/public/ into the same commit"
|
||||||
echo " • Stash unstaged changes during build process"
|
|
||||||
echo " • Restore your unstaged changes after the push"
|
|
||||||
echo ""
|
|
||||||
echo "To test the hooks:"
|
|
||||||
echo " • Make a change to a file in the webui directory and commit it (triggers format/check)"
|
|
||||||
echo " • Push your commits to trigger the build process"
|
|
||||||
else
|
else
|
||||||
echo "❌ Failed to make hooks executable"
|
echo "❌ Failed to make hook executable"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
rm -rf ../public/_app;
|
rm -rf ../public/_app;
|
||||||
rm ../public/favicon.svg;
|
rm ../public/favicon.svg;
|
||||||
rm ../public/index.html;
|
rm -f ../public/index.html.gz; # deprecated, but may still be generated by older versions of the build process
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,17 @@
|
||||||
--code-background: oklch(0.985 0 0);
|
--code-background: oklch(0.985 0 0);
|
||||||
--code-foreground: oklch(0.145 0 0);
|
--code-foreground: oklch(0.145 0 0);
|
||||||
--layer-popover: 1000000;
|
--layer-popover: 1000000;
|
||||||
|
|
||||||
|
--chat-form-area-height: 8rem;
|
||||||
|
--chat-form-area-offset: 2rem;
|
||||||
|
--max-message-height: max(24rem, min(80dvh, calc(100dvh - var(--chat-form-area-height) - 12rem)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 640px) {
|
||||||
|
:root {
|
||||||
|
--chat-form-area-height: 24rem;
|
||||||
|
--chat-form-area-offset: 12rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark {
|
.dark {
|
||||||
|
|
@ -116,19 +127,6 @@
|
||||||
--color-sidebar-ring: var(--sidebar-ring);
|
--color-sidebar-ring: var(--sidebar-ring);
|
||||||
}
|
}
|
||||||
|
|
||||||
:root {
|
|
||||||
--chat-form-area-height: 8rem;
|
|
||||||
--chat-form-area-offset: 2rem;
|
|
||||||
--max-message-height: max(24rem, min(80dvh, calc(100dvh - var(--chat-form-area-height) - 12rem)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 640px) {
|
|
||||||
:root {
|
|
||||||
--chat-form-area-height: 24rem;
|
|
||||||
--chat-form-area-offset: 12rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
* {
|
* {
|
||||||
@apply border-border outline-ring/50;
|
@apply border-border outline-ring/50;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ const config = {
|
||||||
strict: true
|
strict: true
|
||||||
}),
|
}),
|
||||||
output: {
|
output: {
|
||||||
bundleStrategy: 'inline'
|
bundleStrategy: 'single'
|
||||||
},
|
},
|
||||||
alias: {
|
alias: {
|
||||||
$styles: 'src/styles'
|
$styles: 'src/styles'
|
||||||
|
|
|
||||||
|
|
@ -2,5 +2,5 @@ import { expect, test } from '@playwright/test';
|
||||||
|
|
||||||
test('home page has expected h1', async ({ page }) => {
|
test('home page has expected h1', async ({ page }) => {
|
||||||
await page.goto('/');
|
await page.goto('/');
|
||||||
await expect(page.locator('h1')).toBeVisible();
|
await expect(page.locator('h1').first()).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import tailwindcss from '@tailwindcss/vite';
|
import tailwindcss from '@tailwindcss/vite';
|
||||||
import { sveltekit } from '@sveltejs/kit/vite';
|
import { sveltekit } from '@sveltejs/kit/vite';
|
||||||
import * as fflate from 'fflate';
|
import { readFileSync, writeFileSync, existsSync, readdirSync, copyFileSync } from 'fs';
|
||||||
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
|
||||||
import { dirname, resolve } from 'path';
|
import { dirname, resolve } from 'path';
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
|
|
||||||
|
|
@ -20,15 +19,13 @@ const GUIDE_FOR_FRONTEND = `
|
||||||
-->
|
-->
|
||||||
`.trim();
|
`.trim();
|
||||||
|
|
||||||
const MAX_BUNDLE_SIZE = 2 * 1024 * 1024;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the maximum size of an embedded asset in bytes,
|
* the maximum size of an embedded asset in bytes,
|
||||||
* e.g. maximum size of embedded font (see node_modules/katex/dist/fonts/*.woff2)
|
* e.g. maximum size of embedded font (see node_modules/katex/dist/fonts/*.woff2)
|
||||||
*/
|
*/
|
||||||
const MAX_ASSET_SIZE = 32000;
|
const MAX_ASSET_SIZE = 32000;
|
||||||
|
|
||||||
/** public/index.html.gz minified flag */
|
/** public/index.html minified flag */
|
||||||
const ENABLE_JS_MINIFICATION = true;
|
const ENABLE_JS_MINIFICATION = true;
|
||||||
|
|
||||||
function llamaCppBuildPlugin() {
|
function llamaCppBuildPlugin() {
|
||||||
|
|
@ -40,7 +37,6 @@ function llamaCppBuildPlugin() {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
try {
|
try {
|
||||||
const indexPath = resolve('../public/index.html');
|
const indexPath = resolve('../public/index.html');
|
||||||
const gzipPath = resolve('../public/index.html.gz');
|
|
||||||
|
|
||||||
if (!existsSync(indexPath)) {
|
if (!existsSync(indexPath)) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -61,26 +57,35 @@ function llamaCppBuildPlugin() {
|
||||||
|
|
||||||
content = content.replace(/\r/g, '');
|
content = content.replace(/\r/g, '');
|
||||||
content = GUIDE_FOR_FRONTEND + '\n' + content;
|
content = GUIDE_FOR_FRONTEND + '\n' + content;
|
||||||
|
content = content.replace(/\/_app\/immutable\/bundle\.[^"]+\.js/g, './bundle.js');
|
||||||
|
content = content.replace(
|
||||||
|
/\/_app\/immutable\/assets\/bundle\.[^"]+\.css/g,
|
||||||
|
'./bundle.css'
|
||||||
|
);
|
||||||
|
|
||||||
const compressed = fflate.gzipSync(Buffer.from(content, 'utf-8'), { level: 9 });
|
writeFileSync(indexPath, content, 'utf-8');
|
||||||
|
console.log('✓ Updated index.html');
|
||||||
|
|
||||||
compressed[0x4] = 0;
|
// Copy bundle.*.js -> ../public/bundle.js
|
||||||
compressed[0x5] = 0;
|
const immutableDir = resolve('../public/_app/immutable');
|
||||||
compressed[0x6] = 0;
|
const bundleDir = resolve('../public/_app/immutable/assets');
|
||||||
compressed[0x7] = 0;
|
if (existsSync(immutableDir)) {
|
||||||
compressed[0x9] = 0;
|
const jsFiles = readdirSync(immutableDir).filter((f) => f.match(/^bundle\..+\.js$/));
|
||||||
|
if (jsFiles.length > 0) {
|
||||||
if (compressed.byteLength > MAX_BUNDLE_SIZE) {
|
copyFileSync(resolve(immutableDir, jsFiles[0]), resolve('../public/bundle.js'));
|
||||||
throw new Error(
|
console.log(`✓ Copied ${jsFiles[0]} -> bundle.js`);
|
||||||
`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`
|
}
|
||||||
);
|
// Copy bundle.*.css -> ../public/bundle.css
|
||||||
|
if (existsSync(bundleDir)) {
|
||||||
|
const cssFiles = readdirSync(bundleDir).filter((f) => f.match(/^bundle\..+\.css$/));
|
||||||
|
if (cssFiles.length > 0) {
|
||||||
|
copyFileSync(resolve(bundleDir, cssFiles[0]), resolve('../public/bundle.css'));
|
||||||
|
console.log(`✓ Copied ${cssFiles[0]} -> bundle.css`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writeFileSync(gzipPath, compressed);
|
|
||||||
console.log('✓ Created index.html.gz');
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to create gzip file:', error);
|
console.error('Failed to update index.html:', error);
|
||||||
}
|
}
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue