| 'use strict'; |
| const mimicFn = require('mimic-fn'); |
| |
| module.exports = (fn, opts) => { |
| // TODO: Remove this in v3 |
| if (opts === true) { |
| throw new TypeError('The second argument is now an options object'); |
| } |
| |
| if (typeof fn !== 'function') { |
| throw new TypeError('Expected a function'); |
| } |
| |
| opts = opts || {}; |
| |
| let ret; |
| let called = false; |
| const fnName = fn.displayName || fn.name || '<anonymous>'; |
| |
| const onetime = function () { |
| if (called) { |
| if (opts.throw === true) { |
| throw new Error(`Function \`${fnName}\` can only be called once`); |
| } |
| |
| return ret; |
| } |
| |
| called = true; |
| ret = fn.apply(this, arguments); |
| fn = null; |
| |
| return ret; |
| }; |
| |
| mimicFn(onetime, fn); |
| |
| return onetime; |
| }; |