sqlite-wasm 0.1.4

A high-performance SQLite wrapper for WebAssembly with OPFS support
#!/bin/bash

# CONFIGURAÇÕES
PORT=8080
SERVER_ENABLED=true  # Mude para false se nΓ£o quiser iniciar servidor

echo "πŸš€ Starting optimization pipeline..."

# ==================== CREATE HEADERS FILE ====================
echo "πŸ“‹ Creating _headers file..."
cat > _headers << 'EOF'
/*
  Cross-Origin-Opener-Policy: same-origin
  Cross-Origin-Embedder-Policy: require-corp
  Access-Control-Allow-Origin: *
  Access-Control-Allow-Methods: GET, POST, OPTIONS
EOF

# ==================== MINIFY SQLITE SOURCES (TEMPORARY) ====================
echo "βœ‚οΈ Creating minified copies of SQLite files..."

# Cria pasta temporΓ‘ria
mkdir -p tmp_minified

# Minifica com terser (usa node_modules local)
TERSER="./node_modules/.bin/terser"

# Verifica se terser existe
if [ ! -f "$TERSER" ]; then
    echo "πŸ“¦ Installing terser locally..."
    npm install terser
fi

# Array de arquivos SQLite para minificar
SQLITE_FILES=(
    "static/sqlite.org/sqlite3.js"
    "static/sqlite.org/sqlite3-worker1.js" 
    "static/sqlite.org/sqlite3-opfs-async-proxy.js"
)

# Minifica cada arquivo e guarda tamanhos
declare -A original_sizes
declare -A minified_sizes

for file in "${SQLITE_FILES[@]}"; do
    filename=$(basename "$file")
    original_sizes[$filename]=$(stat -c%s "$file" 2>/dev/null || stat -f%z "$file" 2>/dev/null)
    
    $TERSER "$file" -o "tmp_minified/$filename" --compress --mangle 2>/dev/null
    minified_sizes[$filename]=$(stat -c%s "tmp_minified/$filename" 2>/dev/null || stat -f%z "tmp_minified/$filename" 2>/dev/null)
    
    # Backup e substitui
    cp "$file" "$file.bak"
    cp "tmp_minified/$filename" "$file"
done

# Mostra reduΓ§Γ£o de tamanho
echo "πŸ“Š SQLite files size reduction:"
for file in "${SQLITE_FILES[@]}"; do
    filename=$(basename "$file")
    saved=$((original_sizes[$filename] - minified_sizes[$filename]))
    percent=$(echo "scale=1; $saved * 100 / ${original_sizes[$filename]}" | bc 2>/dev/null || echo "0")
    printf "  %-30s %'8d β†’ %'8d bytes (%.1f%% smaller)\n" \
        "$filename" "${original_sizes[$filename]}" "${minified_sizes[$filename]}" "$percent"
done

# ==================== BUILD ====================
echo "πŸ“¦ Building with Trunk..."
trunk build --release

# ==================== RESTORE ORIGINALS ====================
echo "♻️ Restoring original SQLite files..."
for file in "${SQLITE_FILES[@]}"; do
    mv "$file.bak" "$file"
done

# Limpa temporΓ‘rios
rm -rf tmp_minified

# ==================== COPY HEADERS ====================
echo "πŸ“‹ Copying headers to dist..."
cp _headers dist/_headers
rm _headers

# ==================== NODE_MODULES LOCAL ====================
echo "πŸ“¦ Setting up local node_modules..."
if [ ! -d "node_modules" ]; then
    npm install terser clean-css-cli html-minifier compression
fi

# ==================== USAR NODE_MODULES LOCAL ====================
TERSER="./node_modules/.bin/terser"
CLEANCSS="./node_modules/.bin/cleancss"
HTML_MINIFIER="./node_modules/.bin/html-minifier"

# ==================== MINIFICATION WITH TERSER ====================
echo "πŸ”₯ Minifying JavaScript files with Terser..."

# OtimizaΓ§Γ£o: sΓ³ minifica arquivos .js que nΓ£o sejam os SQLite (jΓ‘ minificados)
find dist -name "*.js" -type f ! -path "*/sqlite.org/*" | while read file; do
    if [ -f "$file" ]; then
        original_size=$(stat -c%s "$file" 2>/dev/null || stat -f%z "$file" 2>/dev/null)
        $TERSER "$file" -o "$file" --compress --mangle 2>/dev/null
        new_size=$(stat -c%s "$file" 2>/dev/null || stat -f%z "$file" 2>/dev/null)
        saved=$((original_size - new_size))
        percent=$(echo "scale=1; $saved * 100 / $original_size" | bc 2>/dev/null || echo "0")
        printf "   βœ… %-40s %'8d β†’ %'8d bytes (%.1f%% smaller)\n" "$(basename $file)" "$original_size" "$new_size" "$percent"
    fi
done

# ==================== CSS MINIFICATION ====================
echo "🎨 Minifying CSS files..."

find dist -name "*.css" -type f | while read file; do
    if [ -f "$file" ]; then
        original_size=$(stat -c%s "$file" 2>/dev/null || stat -f%z "$file" 2>/dev/null)
        $CLEANCSS -o "$file" "$file" 2>/dev/null
        new_size=$(stat -c%s "$file" 2>/dev/null || stat -f%z "$file" 2>/dev/null)
        printf "   βœ… %-40s %'8d β†’ %'8d bytes\n" "$(basename $file)" "$original_size" "$new_size"
    fi
done

# ==================== HTML MINIFICATION ====================
echo "🌐 Minifying HTML..."

if [ -f "dist/index.html" ]; then
    original_size=$(stat -c%s "dist/index.html" 2>/dev/null || stat -f%z "dist/index.html" 2>/dev/null)
    $HTML_MINIFIER --collapse-whitespace --remove-comments --minify-js true --minify-css true -o dist/index.html.tmp dist/index.html
    mv dist/index.html.tmp dist/index.html
    new_size=$(stat -c%s "dist/index.html" 2>/dev/null || stat -f%z "dist/index.html" 2>/dev/null)
    printf "   βœ… %-40s %'8d β†’ %'8d bytes\n" "index.html" "$original_size" "$new_size"
fi

# ==================== WASM COMPRESSION ====================
echo "πŸ”’ Compressing WASM files..."

if command -v brotli &> /dev/null; then
    find dist -name "*.wasm" -type f -exec brotli -q 11 -f -k {} \;
    echo "   βœ… Brotli compression complete"
fi

if command -v gzip &> /dev/null; then
    find dist -name "*.wasm" -type f -exec gzip -9 -f -k {} \;
    echo "   βœ… Gzip compression complete"
fi

# ==================== CREATE EXPRESS SERVER ====================
echo "πŸ“ Creating Express server with compression and headers..."

cat > dist/server.js << 'EOF'
const express = require('express');
const compression = require('compression');
const path = require('path');

const app = express();
const PORT = process.env.PORT || 8080;

// Enable compression (gzip/brotli)
app.use(compression());

// COOP/COEP headers
app.use((req, res, next) => {
    res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
    res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp');
    res.setHeader('Cache-Control', 'public, max-age=31536000, immutable');
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
    next();
});

// Serve static files
app.use(express.static(path.join(__dirname)));

// SPA fallback (if needed)
app.get('*', (req, res) => {
    res.sendFile(path.join(__dirname, 'index.html'));
});

app.listen(PORT, () => {
    console.log(`πŸš€ Server running at http://localhost:${PORT}`);
    console.log(`πŸ”’ COOP/COEP headers enabled`);
    console.log(`πŸ“¦ Compression: gzip/brotli enabled`);
});
EOF

# ==================== CREATE PACKAGE.JSON FOR SERVER ====================
cat > dist/package.json << 'EOF'
{
  "name": "sqlite-wasm-server",
  "version": "1.0.0",
  "private": true,
  "dependencies": {
    "express": "^4.18.2",
    "compression": "^1.7.4"
  },
  "scripts": {
    "start": "node server.js"
  }
}
EOF

# ==================== TRUNK CLEANUP ====================
echo "🧹 Cleaning Trunk variables..."
sed -i 's/{{__trunk_address__}}//g; s/{{__trunk_ws_base__}}//g' dist/index.html

# ==================== INSTALL SERVER DEPENDENCIES ====================
echo "πŸ“¦ Installing server dependencies..."
cd dist && npm install
cd ..

# ==================== FINAL REPORT ====================
echo ""
echo "πŸ“Š OPTIMIZATION SUMMARY"
echo "================================================================================"

# Mostra os principais arquivos com tamanhos
echo "  Main files:"
ls -lh dist/sqlite-wasm.js 2>/dev/null | awk '{printf "    sqlite-wasm.js: %s\n", $5}'
ls -lh dist/sqlite-wasm_bg.wasm 2>/dev/null | awk '{printf "    sqlite-wasm_bg.wasm: %s\n", $5}'
ls -lh dist/sqlite-wasm_bg.wasm.gz 2>/dev/null | awk '{printf "    sqlite-wasm_bg.wasm.gz: %s\n", $5}'
ls -lh dist/sqlite-wasm_bg.wasm.br 2>/dev/null | awk '{printf "    sqlite-wasm_bg.wasm.br: %s\n", $5}'

echo ""
echo "  Frontend JS:"
ls -lh dist/static/sqlite-wasm/js/*.js 2>/dev/null | awk '{printf "    %s: %s\n", $9, $5}'

echo ""
echo "  SQLite files (now minified in blobs):"
for file in "${SQLITE_FILES[@]}"; do
    filename=$(basename "$file")
    printf "    minified %s: %'8d bytes (was %'8d, saved %'d)\n" \
        "$filename" "${minified_sizes[$filename]}" "${original_sizes[$filename]}" \
        $((original_sizes[$filename] - minified_sizes[$filename]))
done

echo "================================================================================"
echo ""
echo "βœ… Build complete! Ready to deploy to Cloudflare."
echo ""

# ==================== START SERVER (OPTIONAL) ====================
if [ "$SERVER_ENABLED" = true ]; then
    echo "🌐 Starting Express server with compression and headers..."
    echo "   Press Ctrl+C to stop"
    echo ""
    cd dist && node server.js
else
    echo "🌐 Server not started (SERVER_ENABLED=$SERVER_ENABLED)"
    echo "   To start manually: cd dist && node server.js"
fi