45 lines
		
	
	
		
			1.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			45 lines
		
	
	
		
			1.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict';
 | |
| const mimicFn = require('mimic-fn');
 | |
| 
 | |
| const calledFunctions = new WeakMap();
 | |
| 
 | |
| const onetime = (function_, options = {}) => {
 | |
| 	if (typeof function_ !== 'function') {
 | |
| 		throw new TypeError('Expected a function');
 | |
| 	}
 | |
| 
 | |
| 	let returnValue;
 | |
| 	let callCount = 0;
 | |
| 	const functionName = function_.displayName || function_.name || '<anonymous>';
 | |
| 
 | |
| 	const onetime = function (...arguments_) {
 | |
| 		calledFunctions.set(onetime, ++callCount);
 | |
| 
 | |
| 		if (callCount === 1) {
 | |
| 			returnValue = function_.apply(this, arguments_);
 | |
| 			function_ = null;
 | |
| 		} else if (options.throw === true) {
 | |
| 			throw new Error(`Function \`${functionName}\` can only be called once`);
 | |
| 		}
 | |
| 
 | |
| 		return returnValue;
 | |
| 	};
 | |
| 
 | |
| 	mimicFn(onetime, function_);
 | |
| 	calledFunctions.set(onetime, callCount);
 | |
| 
 | |
| 	return onetime;
 | |
| };
 | |
| 
 | |
| module.exports = onetime;
 | |
| // TODO: Remove this for the next major release
 | |
| module.exports.default = onetime;
 | |
| 
 | |
| module.exports.callCount = function_ => {
 | |
| 	if (!calledFunctions.has(function_)) {
 | |
| 		throw new Error(`The given function \`${function_.name}\` is not wrapped by the \`onetime\` package`);
 | |
| 	}
 | |
| 
 | |
| 	return calledFunctions.get(function_);
 | |
| };
 |