// Copies the production dictionary DAWGs into the build's app assets so a native (offline-first) // install can obtain a dictionary with no network: the loader's bundled tier fetches // ./dict/.dawg, where dictKey is "@" (see lib/dict/store.ts). Run only in // the native pipeline (after `pnpm build`, before `cap sync`); web builds skip it and stay slim. // // Source: DICT_DIR — the unpacked scrabble-dictionary release (scrabble-dawg-.tar.gz), // the SAME set the backend image and CI consume, NOT the solver's committed test fixtures. The bundled // version label comes from VITE_DICT_VERSION (default "dev") and MUST equal the client's __DICT_VERSION__ // so the loader requests the exact (variant, version) the file is named for. OUT_DIR overrides the // output root (default `dist`) — the e2e build points it at dist-e2e. import { existsSync, mkdirSync, copyFileSync } from 'node:fs'; import { join } from 'node:path'; const srcDir = process.env.DICT_DIR; if (!srcDir) { console.error('bundle-dicts: DICT_DIR is required (the unpacked scrabble-dictionary release dir)'); process.exit(1); } const version = process.env.VITE_DICT_VERSION || 'dev'; const outDir = join(process.env.OUT_DIR || 'dist', 'dict'); // The app's Variant enum value -> the release dawg file name (matches e2e-dict.mjs and the movegen // parity mapping). const dawgFor = { scrabble_en: 'en_sowpods', scrabble_ru: 'ru_scrabble', erudit_ru: 'ru_erudit', }; mkdirSync(outDir, { recursive: true }); let copied = 0; for (const [variant, file] of Object.entries(dawgFor)) { const src = join(srcDir, `${file}.dawg`); if (!existsSync(src)) { console.warn(`bundle-dicts: missing ${src} — the bundled tier will 404 for ${variant} (set DICT_DIR)`); continue; } copyFileSync(src, join(outDir, `${variant}@${version}.dawg`)); copied++; } console.log(`bundle-dicts: copied ${copied}/${Object.keys(dawgFor).length} dawgs -> ${outDir} (version ${version})`);