eventLoop processes file system events
()
| 79 | |
| 80 | // eventLoop processes file system events |
| 81 | func (d *Daemon) eventLoop() { |
| 82 | debouncer := newEventDebouncer(100 * time.Millisecond) |
| 83 | |
| 84 | for { |
| 85 | select { |
| 86 | case <-d.done: |
| 87 | return |
| 88 | |
| 89 | case event, ok := <-d.watcher.Events: |
| 90 | if !ok { |
| 91 | return |
| 92 | } |
| 93 | |
| 94 | // Allow directory creates through (to add new dirs to watcher) |
| 95 | // but skip non-source files otherwise |
| 96 | isCreate := event.Op&fsnotify.Create != 0 |
| 97 | if !d.isSourceFile(event.Name) { |
| 98 | // Check if it's a directory create - let those through |
| 99 | if isCreate { |
| 100 | if info, err := os.Stat(event.Name); err == nil && info.IsDir() { |
| 101 | // Directory create - let it through to handleEvent |
| 102 | } else { |
| 103 | continue |
| 104 | } |
| 105 | } else { |
| 106 | continue |
| 107 | } |
| 108 | } |
| 109 | |
| 110 | // Skip build-tool temp files (e.g. vite's |
| 111 | // vite.config.ts.timestamp-*.mjs) so transient churn never |
| 112 | // reaches the event log or working set. |
| 113 | if isTransientFile(event.Name) { |
| 114 | continue |
| 115 | } |
| 116 | |
| 117 | if debouncer.shouldSkip(event, time.Now()) { |
| 118 | continue |
| 119 | } |
| 120 | |
| 121 | // Process the event |
| 122 | d.handleEvent(event) |
| 123 | |
| 124 | case err, ok := <-d.watcher.Errors: |
| 125 | if !ok { |
| 126 | return |
| 127 | } |
| 128 | if d.verbose { |
| 129 | fmt.Printf("[watch] Error: %v\n", err) |
| 130 | } |
| 131 | } |
| 132 | } |
| 133 | } |
| 134 | |
| 135 | // isSourceFile checks if a file should be tracked. |
| 136 | // Derives from the canonical extension registry in scanner. |
no test coverage detected