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