UNPKG

one-firework

Version:

A library for singal use function execution.

85 lines (83 loc) 3.45 kB
// node_modules/mimic-function/index.js var copyProperty = (to, from, property, ignoreNonConfigurable) => { if (property === "length" || property === "prototype") { return; } if (property === "arguments" || property === "caller") { return; } const toDescriptor = Object.getOwnPropertyDescriptor(to, property); const fromDescriptor = Object.getOwnPropertyDescriptor(from, property); if (!canCopyProperty(toDescriptor, fromDescriptor) && ignoreNonConfigurable) { return; } Object.defineProperty(to, property, fromDescriptor); }; var canCopyProperty = function(toDescriptor, fromDescriptor) { return toDescriptor === undefined || toDescriptor.configurable || toDescriptor.writable === fromDescriptor.writable && toDescriptor.enumerable === fromDescriptor.enumerable && toDescriptor.configurable === fromDescriptor.configurable && (toDescriptor.writable || toDescriptor.value === fromDescriptor.value); }; var changePrototype = (to, from) => { const fromPrototype = Object.getPrototypeOf(from); if (fromPrototype === Object.getPrototypeOf(to)) { return; } Object.setPrototypeOf(to, fromPrototype); }; var wrappedToString = (withName, fromBody) => `/* Wrapped ${withName}*/ ${fromBody}`; var toStringDescriptor = Object.getOwnPropertyDescriptor(Function.prototype, "toString"); var toStringName = Object.getOwnPropertyDescriptor(Function.prototype.toString, "name"); var changeToString = (to, from, name) => { const withName = name === "" ? "" : `with ${name.trim()}() `; const newToString = wrappedToString.bind(null, withName, from.toString()); Object.defineProperty(newToString, "name", toStringName); const { writable, enumerable, configurable } = toStringDescriptor; Object.defineProperty(to, "toString", { value: newToString, writable, enumerable, configurable }); }; function mimicFunction(to, from, { ignoreNonConfigurable = false } = {}) { const { name } = to; for (const property of Reflect.ownKeys(from)) { copyProperty(to, from, property, ignoreNonConfigurable); } changePrototype(to, from); changeToString(to, from, name); return to; } // index.ts var calledFunction = new WeakMap; var firework = (function_, options = {}) => { if (typeof function_ !== "function") { throw new TypeError(`Expected a function, but received \`${typeof function_}\`. Please pass a function.`); } let originalFunction = function_; let returnValue; let fireCount = 0; const functionName = function_.name || "<anonymous>"; const fireworkFunction = (...args_) => { fireCount++; calledFunction.set(fireworkFunction, fireCount); if (fireCount === 1) { try { returnValue = originalFunction.apply(null, args_); } finally { originalFunction = undefined; } } else if (options.throwOnMaxCalls === true) { throw new Error(`Function \`${functionName}\` can only be called once! Called \`${fireCount}\` times`); } return returnValue; }; mimicFunction(fireworkFunction, originalFunction); return fireworkFunction; }; firework.fired = (wrappedFunction) => { if (!calledFunction.has(wrappedFunction)) { const funcName = wrappedFunction?.name || "<anonymous function>"; throw new Error(`The function \`${funcName}\` was not created by \`firework\` or has not been called yet.`); } return calledFunction.get(wrappedFunction); }; var firework_default = firework; export { firework_default as default };