MCPcopy Create free account
hub / github.com/heygen-com/hyperframes / createProjectWatcher

Function createProjectWatcher

packages/cli/src/server/fileWatcher.ts:32–76  ·  view source on GitHub ↗
(projectDir: string)

Source from the content-addressed store, hash-verified

30}
31
32export function createProjectWatcher(projectDir: string): ProjectWatcher {
33 const listeners = new Set<FileChangeListener>();
34 let debounceTimer: ReturnType<typeof setTimeout> | null = null;
35 let watcher: FSWatcher | null = null;
36
37 try {
38 watcher = watch(projectDir, { recursive: true }, (_event, filename) => {
39 if (!filename) return;
40 const relativePath = filename.toString();
41 if (!shouldWatchProjectFile(relativePath)) return;
42
43 if (debounceTimer) clearTimeout(debounceTimer);
44 debounceTimer = setTimeout(() => {
45 for (const fn of listeners) {
46 fn(relativePath);
47 }
48 }, DEBOUNCE_MS);
49 });
50 // fs.watch can fail asynchronously too (e.g. EMFILE from exhausted OS watch
51 // handles) — that surfaces as an 'error' event, not a thrown exception. An
52 // EventEmitter 'error' with no listener crashes the whole process, so this
53 // listener is required for the same "degrade gracefully" the catch below
54 // already promises for the synchronous failure mode.
55 watcher.on("error", () => {
56 watcher?.close();
57 watcher = null;
58 });
59 } catch {
60 // fs.watch may fail on some platforms — degrade gracefully (no auto-refresh)
61 }
62
63 return {
64 addListener(fn) {
65 listeners.add(fn);
66 },
67 removeListener(fn) {
68 listeners.delete(fn);
69 },
70 close() {
71 if (debounceTimer) clearTimeout(debounceTimer);
72 watcher?.close();
73 listeners.clear();
74 },
75 };
76}

Callers 2

createStudioServerFunction · 0.85

Calls 3

shouldWatchProjectFileFunction · 0.85
onMethod · 0.65
closeMethod · 0.65

Tested by

no test coverage detected