events_run-once.js

const callbacksFired = {};

/**
 * @module runOnce
 * @description Runs a given method only once, regardless of how many times it's called.
 *
 * @since 3.2.1
 *
 * @param {Function} fn The method or function to execute once.
 *
 * @return {Function} A new function that, when called, executes the provided function only once.
 *
 * @example
 * const initializeLogging = initOnce(() => {
 *   console.log('Logging initialized');
 * });
 *
 * initializeLogging(); // Logs 'Logging initialized'
 * initializeLogging(); // No output, as it's already initialized
 *
 */
const runOnce = ( fn ) => {
	const hash = hashFunction( fn );

	if ( undefined === callbacksFired[ hash ] ) {
		callbacksFired[ hash ] = false;
	}

	return function() {
		if ( callbacksFired[ hash ] ) {
			return;
		}

		callbacksFired[ hash ] = true;

		fn.apply( this, arguments );
	};
};

/**
 * @module hashFunction
 * @description Generates a hash for the given function using a simple string-based hashing algorithm.
 *
 * @since 3.2.1
 *
 * @param {Function} fn The function to be hashed.
 *
 * @return {string} A string prefixed with 'orf_' followed by the hash value of the input function.
 *
 * @example
 * const myFunction = function() { console.log('Hello'); };
 * const hash = hashFunction(myFunction);
 * console.log(hash); // Outputs something like 'orf_12345678'
 *
 */
const hashFunction = ( fn ) => {
	const str = String( fn );
	let hash = 0;

	for ( let i = 0, len = str.length; i < len; i++ ) {
		const chr = str.charCodeAt( i );
		hash = ( hash << 5 ) - hash + chr; // eslint-disable-line no-bitwise
		hash |= 0; // eslint-disable-line no-bitwise
	}

	return 'orf_' + hash;
};

export default runOnce;