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.
50 lines
1.0 KiB
50 lines
1.0 KiB
'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); |
|
};
|
|
|