index.js 1.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. 'use strict';
  2. const mimicFn = require('mimic-fn');
  3. const calledFunctions = new WeakMap();
  4. const oneTime = (fn, options = {}) => {
  5. if (typeof fn !== 'function') {
  6. throw new TypeError('Expected a function');
  7. }
  8. let ret;
  9. let isCalled = false;
  10. let callCount = 0;
  11. const functionName = fn.displayName || fn.name || '<anonymous>';
  12. const onetime = function (...args) {
  13. calledFunctions.set(onetime, ++callCount);
  14. if (isCalled) {
  15. if (options.throw === true) {
  16. throw new Error(`Function \`${functionName}\` can only be called once`);
  17. }
  18. return ret;
  19. }
  20. isCalled = true;
  21. ret = fn.apply(this, args);
  22. fn = null;
  23. return ret;
  24. };
  25. mimicFn(onetime, fn);
  26. calledFunctions.set(onetime, callCount);
  27. return onetime;
  28. };
  29. module.exports = oneTime;
  30. // TODO: Remove this for the next major release
  31. module.exports.default = oneTime;
  32. module.exports.callCount = fn => {
  33. if (!calledFunctions.has(fn)) {
  34. throw new Error(`The given function \`${fn.name}\` is not wrapped by the \`onetime\` package`);
  35. }
  36. return calledFunctions.get(fn);
  37. };