You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							211 lines
						
					
					
						
							4.8 KiB
						
					
					
				
			
		
		
	
	
							211 lines
						
					
					
						
							4.8 KiB
						
					
					
				/* | 
						|
	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;
 | 
						|
 |