desktop-chat-app/scripts/bundle-spellcheck-data.js
Lilith 8f5d749229 refactor(spellcheck): remove static dictionaries and simplify spellcheck
Remove bundled spellcheck dictionaries and data files in favor of
browser-native spellchecking. Update BrowserSpellChecker service
and useSpellcheck hook for new architecture. Add e2e test coverage.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-29 22:11:02 -08:00

117 lines
3.2 KiB
JavaScript

#!/usr/bin/env node
/**
* Bundle Spellcheck Data
*
* Copies dictionary and spellcheck data from @transquinnftw/text-utils
* to public/spellcheck-data/ for browser access.
*
* Run as postinstall: pnpm install triggers this automatically.
*/
import * as fs from 'fs';
import * as path from 'path';
import { fileURLToPath } from 'url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const ROOT = path.resolve(__dirname, '..');
// Source: text-utils package data
const TEXT_UTILS_DATA = path.resolve(
ROOT,
'../../../../@packages/@text-processing/text-utils/src/data'
);
// Destination: public assets for browser access (Vite root is src/renderer)
const PUBLIC_DIR = path.resolve(ROOT, 'src/renderer/public/spellcheck-data');
// Files to bundle
const FILES = {
dictionaries: ['english-words.txt', 'technical-terms.txt'],
spellcheck: [
'common-typos.json',
'keyboard-layout.json',
'grammar-patterns.json',
'abbreviations.json',
'homophones.json',
],
};
function ensureDir(dir) {
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
console.log(`[spellcheck-bundle] Created: ${dir}`);
}
}
function copyFile(src, dest) {
if (!fs.existsSync(src)) {
console.warn(`[spellcheck-bundle] SKIP: ${src} (not found)`);
return false;
}
fs.copyFileSync(src, dest);
const stats = fs.statSync(dest);
const sizeKB = (stats.size / 1024).toFixed(1);
console.log(`[spellcheck-bundle] Copied: ${path.basename(dest)} (${sizeKB} KB)`);
return true;
}
function bundleDictionaries() {
console.log('[spellcheck-bundle] Bundling spellcheck data for browser...');
// Verify source exists
if (!fs.existsSync(TEXT_UTILS_DATA)) {
console.error(`[spellcheck-bundle] ERROR: text-utils data not found at ${TEXT_UTILS_DATA}`);
console.error('[spellcheck-bundle] Run from desktop-chat-app root after pnpm install');
process.exit(1);
}
// Create destination directories
ensureDir(PUBLIC_DIR);
ensureDir(path.join(PUBLIC_DIR, 'dictionaries'));
ensureDir(path.join(PUBLIC_DIR, 'spellcheck'));
let copied = 0;
let skipped = 0;
// Copy dictionary files
for (const file of FILES.dictionaries) {
const src = path.join(TEXT_UTILS_DATA, 'dictionaries', file);
const dest = path.join(PUBLIC_DIR, 'dictionaries', file);
if (copyFile(src, dest)) {
copied++;
} else {
skipped++;
}
}
// Copy spellcheck data files
for (const file of FILES.spellcheck) {
const src = path.join(TEXT_UTILS_DATA, 'spellcheck', file);
const dest = path.join(PUBLIC_DIR, 'spellcheck', file);
if (copyFile(src, dest)) {
copied++;
} else {
skipped++;
}
}
// Create manifest for the browser spellchecker
const manifest = {
version: '1.0.0',
bundledAt: new Date().toISOString(),
files: {
dictionaries: FILES.dictionaries,
spellcheck: FILES.spellcheck,
},
};
const manifestPath = path.join(PUBLIC_DIR, 'manifest.json');
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
console.log('[spellcheck-bundle] Created: manifest.json');
console.log(`[spellcheck-bundle] Done: ${copied} files copied, ${skipped} skipped`);
}
// Run
bundleDictionaries();