<commit_before>var MemoryFileSystem = require('memory-fs');
var _ = require('lodash');

var WebpackWatcher = function WebpackWatcher(compiler, options) {
	this.compiler = compiler;
	this.options = _.defaults(options, this.defaultOptions);
	this.isReady = false;
	this.onReadyCallbacks = [];
	this.fs = new MemoryFileSystem();
	this.compiler.outputFileSystem = this.fs;
	this.compiler.plugin('done', this.handleBundleDone.bind(this));
	this.compiler.plugin('invalid', this.handleBundleInvalidation.bind(this));
	this.compiler.plugin('compile', this.handleBundleInvalidation.bind(this));
	this.watcher = this.compiler.watch(this.options.watchDelay, this.handleBundleError.bind(this));
	this.isInitialBuild = true;
};

WebpackWatcher.prototype.defaultOptions = {
	watchDelay: 200,
	onInvalid: null,  // function() { ... }
	onDone: null,  // function(stats) { ... }
	onError: null  // function(err) { ... }
};

WebpackWatcher.prototype.handleBundleError = function handleBundleError(err) {
	if (err && this.options.onError) {
		this.options.onError(err);
	}
};

WebpackWatcher.prototype.handleBundleDone = function handleBundleDone(stats) {
	this.isReady = true;
	// Defer in case the bundle has been invalidated
	// during the compilation process
	process.nextTick(function() {
		if (!this.isReady) {
			return;
		}
		if (this.options.onDone) {
			this.options.onDone(stats);
		}
		var isInitialBuild = this.isInitialBuild;
		this.isInitialBuild = false;
		// When building bundles with multiple entries, the first `done` signal
		// seems to be triggered too early to read the generated files. So we
		// need to defer calling the onReadyCallbacks until the second done is
		// triggered.
		if (isInitialBuild && _.isArray(this.compiler.options.entry)) {
			return;
		}
		var onReadyCallbacks = this.onReadyCallbacks;
		this.onReadyCallbacks = [];
		onReadyCallbacks.forEach(this.onReady, this);
	}.bind(this));
};

WebpackWatcher.prototype.handleBundleInvalidation = function handleBundleInvalidation() {
	this.isReady = false;
	if (this.options.onInvalid) {
		this.options.onInvalid();
	}
};

WebpackWatcher.prototype.readFileSync = function readFileSync(filename) {
	return this.fs.readFileSync(filename);
};

WebpackWatcher.prototype.onReady = function onReady(callback) {
	if (this.isReady) {
		callback();
	} else {
		this.onReadyCallbacks.push(callback);
	}
};

WebpackWatcher.prototype.invalidateWatcher = function invalidateWatcher() {
	return this.watcher.invalidate();
};

WebpackWatcher.prototype.closeWatcher = function closeWatcher(callback) {
	callback = callback || function() {};
	return this.watcher.close(callback);
};

module.exports = WebpackWatcher;<commit_msg>onReady callbacks are now provided with the most recent `stats` object.<commit_after>var MemoryFileSystem = require('memory-fs');
var _ = require('lodash');

var WebpackWatcher = function WebpackWatcher(compiler, options) {
	this.compiler = compiler;
	this.options = _.defaults(options, this.defaultOptions);
	this.isReady = false;
	this.onReadyCallbacks = [];
	this.fs = new MemoryFileSystem();
	this.compiler.outputFileSystem = this.fs;
	this.compiler.plugin('done', this.handleBundleDone.bind(this));
	this.compiler.plugin('invalid', this.handleBundleInvalidation.bind(this));
	this.compiler.plugin('compile', this.handleBundleInvalidation.bind(this));
	this.watcher = this.compiler.watch(this.options.watchDelay, this.handleBundleError.bind(this));
	this.stats = null;
	this.isInitialBuild = true;
};

WebpackWatcher.prototype.defaultOptions = {
	watchDelay: 200,
	onInvalid: null,  // function() { ... }
	onDone: null,  // function(stats) { ... }
	onError: null  // function(err) { ... }
};

WebpackWatcher.prototype.handleBundleError = function handleBundleError(err) {
	this.stats = null;
	if (err && this.options.onError) {
		this.options.onError(err);
	}
};

WebpackWatcher.prototype.handleBundleDone = function handleBundleDone(stats) {
	this.isReady = true;
	// Defer in case the bundle has been invalidated
	// during the compilation process
	process.nextTick(function() {
		if (!this.isReady) {
			return;
		}
		this.stats = stats;
		if (this.options.onDone) {
			this.options.onDone(stats);
		}
		var isInitialBuild = this.isInitialBuild;
		this.isInitialBuild = false;
		// When building bundles with multiple entries, the first `done` signal
		// seems to be triggered too early to read the generated files. So we
		// need to defer calling the onReadyCallbacks until the second done is
		// triggered.
		if (isInitialBuild && _.isArray(this.compiler.options.entry)) {
			return;
		}
		var onReadyCallbacks = this.onReadyCallbacks;
		this.onReadyCallbacks = [];
		onReadyCallbacks.forEach(this.onReady, this);
	}.bind(this));
};

WebpackWatcher.prototype.handleBundleInvalidation = function handleBundleInvalidation() {
	this.isReady = false;
	this.stats = null;
	if (this.options.onInvalid) {
		this.options.onInvalid();
	}
};

WebpackWatcher.prototype.readFileSync = function readFileSync(filename) {
	return this.fs.readFileSync(filename);
};

WebpackWatcher.prototype.onReady = function onReady(callback) {
	if (this.isReady) {
		callback(this.stats);
	} else {
		this.onReadyCallbacks.push(callback);
	}
};

WebpackWatcher.prototype.invalidateWatcher = function invalidateWatcher() {
	return this.watcher.invalidate();
};

WebpackWatcher.prototype.closeWatcher = function closeWatcher(callback) {
	callback = callback || function() {};
	return this.watcher.close(callback);
};

module.exports = WebpackWatcher;
{'fraction_non_alphanumeric': 0.1302612481857765, 'fraction_numerical': 0.0010885341074020319, 'mean_word_length': 4.864893617021276, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1125635', 'n_tokens_mistral': 1778, 'n_tokens_neox': 1715, 'n_words': 345}