Your music, beautifully tracked. All yours. (coming soon)
teal.fm
teal-fm
atproto
1import chokidar from 'chokidar';
2import { join } from 'path';
3import pc from 'picocolors';
4import { generate } from './generate.js';
5import { findWorkspaceRoot } from '../utils/workspace.js';
6
7interface WatchOptions {
8 tsOnly?: boolean;
9 rustOnly?: boolean;
10}
11
12export async function watch(options: WatchOptions = {}) {
13 const workspaceRoot = findWorkspaceRoot();
14 const lexiconsPath = join(workspaceRoot, 'lexicons');
15
16 console.log(pc.blue('👀 Watching lexicon files for changes...'));
17 console.log(pc.gray(` Lexicons directory: ${lexiconsPath}`));
18 console.log(pc.yellow(' Press Ctrl+C to stop watching'));
19
20 const watcher = chokidar.watch(lexiconsPath, {
21 ignored: /(^|[\/\\])\../, // ignore dotfiles
22 persistent: true,
23 ignoreInitial: true
24 });
25
26 let isGenerating = false;
27
28 const handleChange = async (path: string, event: string) => {
29 if (isGenerating) {
30 console.log(pc.yellow(` ⏳ Skipping ${event} for ${path} (generation in progress)`));
31 return;
32 }
33
34 console.log(pc.cyan(` 📝 ${event}: ${path}`));
35
36 isGenerating = true;
37 try {
38 await generate(options);
39 } catch (error) {
40 console.error(pc.red(' ❌ Auto-generation failed:'), error instanceof Error ? error.message : String(error));
41 } finally {
42 isGenerating = false;
43 }
44 };
45
46 watcher
47 .on('add', (path) => handleChange(path, 'Added'))
48 .on('change', (path) => handleChange(path, 'Changed'))
49 .on('unlink', (path) => handleChange(path, 'Removed'))
50 .on('error', (error) => console.error(pc.red('Watcher error:'), error));
51
52 // Handle graceful shutdown
53 process.on('SIGINT', () => {
54 console.log(pc.yellow('\n🛑 Stopping lexicon watcher...'));
55 watcher.close();
56 process.exit(0);
57 });
58
59 // Keep the process alive
60 return new Promise<void>(() => {});
61}