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.
		
		
		
		
		
			
		
			
				
					
					
						
							176 lines
						
					
					
						
							4.5 KiB
						
					
					
				
			
		
		
	
	
							176 lines
						
					
					
						
							4.5 KiB
						
					
					
				/* | 
						|
	MIT License http://www.opensource.org/licenses/mit-license.php | 
						|
	Author Tobias Koppers @sokra | 
						|
*/ | 
						|
"use strict"; | 
						|
 | 
						|
class Hook { | 
						|
	constructor(args) { | 
						|
		if (!Array.isArray(args)) args = []; | 
						|
		this._args = args; | 
						|
		this.taps = []; | 
						|
		this.interceptors = []; | 
						|
		this.call = this._call; | 
						|
		this.promise = this._promise; | 
						|
		this.callAsync = this._callAsync; | 
						|
		this._x = undefined; | 
						|
	} | 
						|
 | 
						|
	compile(options) { | 
						|
		throw new Error("Abstract: should be overriden"); | 
						|
	} | 
						|
 | 
						|
	_createCall(type) { | 
						|
		return this.compile({ | 
						|
			taps: this.taps, | 
						|
			interceptors: this.interceptors, | 
						|
			args: this._args, | 
						|
			type: type | 
						|
		}); | 
						|
	} | 
						|
 | 
						|
	tap(options, fn) { | 
						|
		if (typeof options === "string") options = { name: options }; | 
						|
		if (typeof options !== "object" || options === null) | 
						|
			throw new Error( | 
						|
				"Invalid arguments to tap(options: Object, fn: function)" | 
						|
			); | 
						|
		options = Object.assign({ type: "sync", fn: fn }, options); | 
						|
		if (typeof options.name !== "string" || options.name === "") | 
						|
			throw new Error("Missing name for tap"); | 
						|
		options = this._runRegisterInterceptors(options); | 
						|
		this._insert(options); | 
						|
	} | 
						|
 | 
						|
	tapAsync(options, fn) { | 
						|
		if (typeof options === "string") options = { name: options }; | 
						|
		if (typeof options !== "object" || options === null) | 
						|
			throw new Error( | 
						|
				"Invalid arguments to tapAsync(options: Object, fn: function)" | 
						|
			); | 
						|
		options = Object.assign({ type: "async", fn: fn }, options); | 
						|
		if (typeof options.name !== "string" || options.name === "") | 
						|
			throw new Error("Missing name for tapAsync"); | 
						|
		options = this._runRegisterInterceptors(options); | 
						|
		this._insert(options); | 
						|
	} | 
						|
 | 
						|
	tapPromise(options, fn) { | 
						|
		if (typeof options === "string") options = { name: options }; | 
						|
		if (typeof options !== "object" || options === null) | 
						|
			throw new Error( | 
						|
				"Invalid arguments to tapPromise(options: Object, fn: function)" | 
						|
			); | 
						|
		options = Object.assign({ type: "promise", fn: fn }, options); | 
						|
		if (typeof options.name !== "string" || options.name === "") | 
						|
			throw new Error("Missing name for tapPromise"); | 
						|
		options = this._runRegisterInterceptors(options); | 
						|
		this._insert(options); | 
						|
	} | 
						|
 | 
						|
	_runRegisterInterceptors(options) { | 
						|
		for (const interceptor of this.interceptors) { | 
						|
			if (interceptor.register) { | 
						|
				const newOptions = interceptor.register(options); | 
						|
				if (newOptions !== undefined) options = newOptions; | 
						|
			} | 
						|
		} | 
						|
		return options; | 
						|
	} | 
						|
 | 
						|
	withOptions(options) { | 
						|
		const mergeOptions = opt => | 
						|
			Object.assign({}, options, typeof opt === "string" ? { name: opt } : opt); | 
						|
 | 
						|
		// Prevent creating endless prototype chains | 
						|
		options = Object.assign({}, options, this._withOptions); | 
						|
		const base = this._withOptionsBase || this; | 
						|
		const newHook = Object.create(base); | 
						|
 | 
						|
		(newHook.tapAsync = (opt, fn) => base.tapAsync(mergeOptions(opt), fn)), | 
						|
			(newHook.tap = (opt, fn) => base.tap(mergeOptions(opt), fn)); | 
						|
		newHook.tapPromise = (opt, fn) => base.tapPromise(mergeOptions(opt), fn); | 
						|
		newHook._withOptions = options; | 
						|
		newHook._withOptionsBase = base; | 
						|
		return newHook; | 
						|
	} | 
						|
 | 
						|
	isUsed() { | 
						|
		return this.taps.length > 0 || this.interceptors.length > 0; | 
						|
	} | 
						|
 | 
						|
	intercept(interceptor) { | 
						|
		this._resetCompilation(); | 
						|
		this.interceptors.push(Object.assign({}, interceptor)); | 
						|
		if (interceptor.register) { | 
						|
			for (let i = 0; i < this.taps.length; i++) | 
						|
				this.taps[i] = interceptor.register(this.taps[i]); | 
						|
		} | 
						|
	} | 
						|
 | 
						|
	_resetCompilation() { | 
						|
		this.call = this._call; | 
						|
		this.callAsync = this._callAsync; | 
						|
		this.promise = this._promise; | 
						|
	} | 
						|
 | 
						|
	_insert(item) { | 
						|
		this._resetCompilation(); | 
						|
		let before; | 
						|
		if (typeof item.before === "string") before = new Set([item.before]); | 
						|
		else if (Array.isArray(item.before)) { | 
						|
			before = new Set(item.before); | 
						|
		} | 
						|
		let stage = 0; | 
						|
		if (typeof item.stage === "number") stage = item.stage; | 
						|
		let i = this.taps.length; | 
						|
		while (i > 0) { | 
						|
			i--; | 
						|
			const x = this.taps[i]; | 
						|
			this.taps[i + 1] = x; | 
						|
			const xStage = x.stage || 0; | 
						|
			if (before) { | 
						|
				if (before.has(x.name)) { | 
						|
					before.delete(x.name); | 
						|
					continue; | 
						|
				} | 
						|
				if (before.size > 0) { | 
						|
					continue; | 
						|
				} | 
						|
			} | 
						|
			if (xStage > stage) { | 
						|
				continue; | 
						|
			} | 
						|
			i++; | 
						|
			break; | 
						|
		} | 
						|
		this.taps[i] = item; | 
						|
	} | 
						|
} | 
						|
 | 
						|
function createCompileDelegate(name, type) { | 
						|
	return function lazyCompileHook(...args) { | 
						|
		this[name] = this._createCall(type); | 
						|
		return this[name](...args); | 
						|
	}; | 
						|
} | 
						|
 | 
						|
Object.defineProperties(Hook.prototype, { | 
						|
	_call: { | 
						|
		value: createCompileDelegate("call", "sync"), | 
						|
		configurable: true, | 
						|
		writable: true | 
						|
	}, | 
						|
	_promise: { | 
						|
		value: createCompileDelegate("promise", "promise"), | 
						|
		configurable: true, | 
						|
		writable: true | 
						|
	}, | 
						|
	_callAsync: { | 
						|
		value: createCompileDelegate("callAsync", "async"), | 
						|
		configurable: true, | 
						|
		writable: true | 
						|
	} | 
						|
}); | 
						|
 | 
						|
module.exports = Hook;
 | 
						|
 |