| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 | /*	MIT License http://www.opensource.org/licenses/mit-license.php	Author Tobias Koppers @sokra*/"use strict";const Stats = require("./Stats");class Watching {	constructor(compiler, watchOptions, handler) {		this.startTime = null;		this.invalid = false;		this.handler = handler;		this.callbacks = [];		this.closed = false;		this.suspended = false;		if (typeof watchOptions === "number") {			this.watchOptions = {				aggregateTimeout: watchOptions			};		} else if (watchOptions && typeof watchOptions === "object") {			this.watchOptions = Object.assign({}, watchOptions);		} else {			this.watchOptions = {};		}		this.watchOptions.aggregateTimeout =			this.watchOptions.aggregateTimeout || 200;		this.compiler = compiler;		this.running = true;		this.compiler.readRecords(err => {			if (err) return this._done(err);			this._go();		});	}	_go() {		this.startTime = Date.now();		this.running = true;		this.invalid = false;		this.compiler.hooks.watchRun.callAsync(this.compiler, err => {			if (err) return this._done(err);			const onCompiled = (err, compilation) => {				if (err) return this._done(err);				if (this.invalid) return this._done();				if (this.compiler.hooks.shouldEmit.call(compilation) === false) {					return this._done(null, compilation);				}				this.compiler.emitAssets(compilation, err => {					if (err) return this._done(err);					if (this.invalid) return this._done();					this.compiler.emitRecords(err => {						if (err) return this._done(err);						if (compilation.hooks.needAdditionalPass.call()) {							compilation.needAdditionalPass = true;							const stats = new Stats(compilation);							stats.startTime = this.startTime;							stats.endTime = Date.now();							this.compiler.hooks.done.callAsync(stats, err => {								if (err) return this._done(err);								this.compiler.hooks.additionalPass.callAsync(err => {									if (err) return this._done(err);									this.compiler.compile(onCompiled);								});							});							return;						}						return this._done(null, compilation);					});				});			};			this.compiler.compile(onCompiled);		});	}	_getStats(compilation) {		const stats = new Stats(compilation);		stats.startTime = this.startTime;		stats.endTime = Date.now();		return stats;	}	_done(err, compilation) {		this.running = false;		if (this.invalid) return this._go();		const stats = compilation ? this._getStats(compilation) : null;		if (err) {			this.compiler.hooks.failed.call(err);			this.handler(err, stats);			return;		}		this.compiler.hooks.done.callAsync(stats, () => {			this.handler(null, stats);			if (!this.closed) {				this.watch(					Array.from(compilation.fileDependencies),					Array.from(compilation.contextDependencies),					Array.from(compilation.missingDependencies)				);			}			for (const cb of this.callbacks) cb();			this.callbacks.length = 0;		});	}	watch(files, dirs, missing) {		this.pausedWatcher = null;		this.watcher = this.compiler.watchFileSystem.watch(			files,			dirs,			missing,			this.startTime,			this.watchOptions,			(				err,				filesModified,				contextModified,				missingModified,				fileTimestamps,				contextTimestamps,				removedFiles			) => {				this.pausedWatcher = this.watcher;				this.watcher = null;				if (err) {					return this.handler(err);				}				this.compiler.fileTimestamps = fileTimestamps;				this.compiler.contextTimestamps = contextTimestamps;				this.compiler.removedFiles = removedFiles;				if (!this.suspended) {					this._invalidate();				}			},			(fileName, changeTime) => {				this.compiler.hooks.invalid.call(fileName, changeTime);			}		);	}	invalidate(callback) {		if (callback) {			this.callbacks.push(callback);		}		if (this.watcher) {			this.compiler.fileTimestamps = this.watcher.getFileTimestamps();			this.compiler.contextTimestamps = this.watcher.getContextTimestamps();		}		return this._invalidate();	}	_invalidate() {		if (this.watcher) {			this.pausedWatcher = this.watcher;			this.watcher.pause();			this.watcher = null;		}		if (this.running) {			this.invalid = true;			return false;		} else {			this._go();		}	}	suspend() {		this.suspended = true;		this.invalid = false;	}	resume() {		if (this.suspended) {			this.suspended = false;			this._invalidate();		}	}	close(callback) {		const finalCallback = () => {			this.compiler.hooks.watchClose.call();			this.compiler.running = false;			this.compiler.watchMode = false;			if (callback !== undefined) callback();		};		this.closed = true;		if (this.watcher) {			this.watcher.close();			this.watcher = null;		}		if (this.pausedWatcher) {			this.pausedWatcher.close();			this.pausedWatcher = null;		}		if (this.running) {			this.invalid = true;			this._done = finalCallback;		} else {			finalCallback();		}	}}module.exports = Watching;
 |