watch.ts
1 /** 2 * Token Watch Script 3 * Watches token JSON files and auto-rebuilds on change 4 * Enables instant feedback loop for design iteration 5 */ 6 7 import { watch } from 'fs'; 8 import { spawn, ChildProcess } from 'child_process'; 9 import { join, dirname } from 'path'; 10 import { fileURLToPath } from 'url'; 11 12 const __dirname = dirname(fileURLToPath(import.meta.url)); 13 const tokensDir = join(__dirname, '..', 'tokens'); 14 15 let buildProcess: ChildProcess | null = null; 16 let debounceTimer: NodeJS.Timeout | null = null; 17 18 function runBuild() { 19 if (buildProcess) { 20 buildProcess.kill(); 21 } 22 23 console.log('\n\x1b[36m[tokens]\x1b[0m Rebuilding...'); 24 const start = Date.now(); 25 26 buildProcess = spawn('tsx', ['scripts/build.ts'], { 27 cwd: join(__dirname, '..'), 28 stdio: 'inherit', 29 shell: true, 30 }); 31 32 buildProcess.on('close', (code) => { 33 if (code === 0) { 34 const duration = Date.now() - start; 35 console.log(`\x1b[32m[tokens]\x1b[0m Ready in ${duration}ms`); 36 } 37 buildProcess = null; 38 }); 39 } 40 41 function debouncedBuild() { 42 if (debounceTimer) { 43 clearTimeout(debounceTimer); 44 } 45 debounceTimer = setTimeout(runBuild, 100); 46 } 47 48 // Watch all JSON files in tokens directory 49 const watchPaths = [ 50 tokensDir, 51 join(tokensDir, 'themes'), 52 ]; 53 54 console.log('\x1b[36m[tokens]\x1b[0m Watching for changes...'); 55 console.log(`\x1b[90m ${tokensDir}\x1b[0m`); 56 console.log(`\x1b[90m ${join(tokensDir, 'themes')}\x1b[0m\n`); 57 58 // Initial build 59 runBuild(); 60 61 // Set up watchers 62 watchPaths.forEach(dir => { 63 watch(dir, { recursive: false }, (eventType, filename) => { 64 if (filename && filename.endsWith('.json')) { 65 console.log(`\x1b[90m[change]\x1b[0m ${filename}`); 66 debouncedBuild(); 67 } 68 }); 69 }); 70 71 // Handle graceful shutdown 72 process.on('SIGINT', () => { 73 console.log('\n\x1b[36m[tokens]\x1b[0m Stopping watch...'); 74 if (buildProcess) buildProcess.kill(); 75 process.exit(0); 76 });