File: fileWatcher.ts

package info (click to toggle)
node-rollup 2.38.4-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 42,968 kB
  • sloc: javascript: 88,384; makefile: 10
file content (67 lines) | stat: -rw-r--r-- 2,069 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import { FSWatcher } from 'chokidar';
const chokidar = require('chokidar');
import { platform } from 'os';
import { ChangeEvent, ChokidarOptions } from '../rollup/types';
import { Task } from './watch';

export class FileWatcher {
	private chokidarOptions: ChokidarOptions;
	private task: Task;
	private transformWatchers = new Map<string, FSWatcher>();
	private watcher: FSWatcher;

	constructor(task: Task, chokidarOptions: ChokidarOptions) {
		this.chokidarOptions = chokidarOptions;
		this.task = task;
		this.watcher = this.createWatcher(null);
	}

	close() {
		this.watcher.close();
		for (const watcher of this.transformWatchers.values()) {
			watcher.close();
		}
	}

	unwatch(id: string) {
		this.watcher.unwatch(id);
		const transformWatcher = this.transformWatchers.get(id);
		if (transformWatcher) {
			this.transformWatchers.delete(id);
			transformWatcher.close();
		}
	}

	watch(id: string, isTransformDependency: boolean) {
		if (isTransformDependency) {
			const watcher = this.transformWatchers.get(id) || this.createWatcher(id);
			watcher.add(id);
			this.transformWatchers.set(id, watcher);
		} else {
			this.watcher.add(id);
		}
	}

	private createWatcher(transformWatcherId: string | null): FSWatcher {
		const task = this.task;
		const isLinux = platform() === 'linux';
		const isTransformDependency = transformWatcherId !== null;
		const handleChange = (id: string, event: ChangeEvent) => {
			const changedId = transformWatcherId || id;
			if (isLinux) {
				// unwatching and watching fixes an issue with chokidar where on certain systems,
				// a file that was unlinked and immediately recreated would create a change event
				// but then no longer any further events
				watcher.unwatch(changedId);
				watcher.add(changedId);
			}
			task.invalidate(changedId, {isTransformDependency, event});
		};
		const watcher = chokidar
			.watch([], this.chokidarOptions)
			.on('add', id => handleChange(id, 'create'))
			.on('change', id => handleChange(id, 'update'))
			.on('unlink', id => handleChange(id, 'delete'));
		return watcher;
	}
}