import { watch } from 'node:fs'; import { access } from 'node:fs/promises'; import path from 'node:path'; import { spawn } from 'node:child_process'; const repositoryRoot = path.resolve(process.cwd()); const layoutsRoot = path.resolve(process.env.CARD_LAYOUTS_ROOT ?? path.join(repositoryRoot, '../../../tools/card-layouts')); const renderScript = path.join(repositoryRoot, 'scripts/render_card_layouts.sh'); const watched = [ [path.join(repositoryRoot, 'json'), name => name === 'card_source.json'], [path.join(repositoryRoot, 'doc/assets'), () => true], [path.join(layoutsRoot, 'react/src'), name => /\.(tsx?|css)$/.test(name)], [path.join(layoutsRoot, 'react'), name => /^(build\.mjs|tsconfig\.json)$/.test(name)], [path.join(layoutsRoot, 'tools'), name => name === 'render_card.py'], [path.join(layoutsRoot, 'schemas'), name => name === 'card-source.schema.json'] ]; let build = null; let queued = false; let debounce = null; function render() { if (build) { queued = true; return; } process.stdout.write('[card-dev] generowanie karty…\n'); build = spawn(renderScript, { cwd: repositoryRoot, env: { ...process.env, CARD_LAYOUTS_ROOT: layoutsRoot }, stdio: 'inherit' }); build.once('exit', code => { build = null; process.stdout.write(code === 0 ? '[card-dev] karta gotowa; przeglądarka odświeży się automatycznie.\n' : `[card-dev] generator zakończył się kodem ${code}.\n`); if (queued) { queued = false; render(); } }); } function scheduleRender() { clearTimeout(debounce); debounce = setTimeout(render, 180); } await access(renderScript); for (const [directory, accepts] of watched) { try { await access(directory); watch(directory, (_event, filename) => { if (filename && accepts(String(filename))) scheduleRender(); }); process.stdout.write(`[card-dev] obserwuję ${directory}\n`); } catch { process.stderr.write(`[card-dev] pomijam brakujący katalog ${directory}\n`); } } const server = spawn(process.execPath, ['--watch', 'scripts/card_server.mjs'], { cwd: repositoryRoot, stdio: 'inherit' }); const stop = signal => { if (build) build.kill(signal); server.kill(signal); process.exit(0); }; process.on('SIGINT', () => stop('SIGINT')); process.on('SIGTERM', () => stop('SIGTERM')); render();