Skip to content
Snippets Groups Projects
Select Git revision
  • 14beaadbe3942b11d98dbcc6cd054b5a878c19d6
  • master default protected
  • 1.31
  • 4.38.2
  • 4.38.1
  • 4.38.0
  • 4.37.2
  • 4.37.1
  • 4.37.0
  • 4.36.0
  • 4.35.0
  • 4.34.1
  • 4.34.0
  • 4.33.1
  • 4.33.0
  • 4.32.2
  • 4.32.1
  • 4.32.0
  • 4.31.0
  • 4.30.1
  • 4.30.0
  • 4.29.1
  • 4.29.0
23 results

processing.mjs

Blame
  • Volker Schukai's avatar
    14beaadb
    History
    processing.mjs 3.78 KiB
    /**
     * Copyright schukai GmbH and contributors 2023. All Rights Reserved.
     * Node module: @schukai/monster
     * This file is licensed under the AGPLv3 License.
     * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
     */
    
    import { internalSymbol } from "../constants.mjs";
    import { Base } from "../types/base.mjs";
    import { getGlobalFunction } from "../types/global.mjs";
    import { isFunction, isInteger } from "../types/is.mjs";
    import { Queue } from "../types/queue.mjs";
    import { validateFunction, validateInteger } from "../types/validate.mjs";
    
    export { Processing };
    
    /**
     * @private
     */
    class Callback {
    	/**
    	 *
    	 * @param {function} callback
    	 * @param {int|undefined} time
    	 * @throws {TypeError} value is not a function
    	 * @throws {TypeError} value is not an integer
    	 * @private
    	 */
    	constructor(callback, time) {
    		this[internalSymbol] = {
    			callback: validateFunction(callback),
    			time: validateInteger(time ?? 0),
    		};
    	}
    
    	/**
    	 * @private
    	 * @param  {*} data
    	 * @return {Promise}
    	 */
    	run(data) {;
    		return new Promise((resolve, reject) => {
    			getGlobalFunction("setTimeout")(() => {
    				try {
    					resolve(this[internalSymbol].callback(data));
    				} catch (e) {
    					reject(e);
    				}
    			}, this[internalSymbol].time);
    		});
    	}
    }
    
    /**
     * This class allows to execute several functions in order.
     *
     * Functions and timeouts can be passed. If a timeout is passed, it applies to all further functions.
     * In the example
     *
     * `timeout1, function1, function2, function3, timeout2, function4`
     *
     * the timeout1 is valid for the functions 1, 2 and 3 and the timeout2 for the function4.
     *
     * So the execution time is timeout1+timeout1+timeout1+timeout2
     *
     * The result of `run()` is a promise.
     *
     * @externalExample ../../example/util/processing.mjs
     * @copyright schukai GmbH
     * @license AGPLv3
     * @since 1.21.0
     * @memberOf Monster.Util
     * @summary Class to be able to execute function chains
     */
    class Processing extends Base {
    	/**
    	 * Create new Processing
    	 *
    	 * Functions and timeouts can be passed. If a timeout is passed, it applies to all further functions.
    	 * In the example
    	 *
    	 * `timeout1, function1, function2, function3, timeout2, function4`
    	 *
    	 * the timeout1 is valid for the functions 1, 2 and 3 and the timeout2 for the function4.
    	 *
    	 * So the execution time is timeout1+timeout1+timeout1+timeout2
    	 *
    	 * @throw {TypeError} the arguments must be either integer or functions
    	 * @param {...(int|function)} args
    	 */
    	constructor(...args) {
    		super();
    
    		this[internalSymbol] = {
    			queue: new Queue(),
    		};
    
    		let time = 0;
    
    		if (typeof args !== "object" || args[0] === null) {
    			throw new TypeError("the arguments must be either integer or functions");
    		}
    
    		for (const [, arg] of Object.entries(args)) {
    			if (isInteger(arg) && arg >= 0) {
    				time = arg;
    			} else if (isFunction(arg)) {
    				this[internalSymbol].queue.add(new Callback(arg, time));
    			} else {
    				throw new TypeError(
    					"the arguments must be either integer or functions",
    				);
    			}
    		}
    	}
    
    	/**
    	 * Adds a function with the desired timeout
    	 * If no timeout is specified, the timeout of the previous function is used.
    	 *
    	 * @param {function} callback
    	 * @param {int|undefined} time
    	 * @throws {TypeError} value is not a function
    	 * @throws {TypeError} value is not an integer
    	 */
    	add(callback, time) {
    		this[internalSymbol].queue.add(new Callback(callback, time));
    		return this;
    	}
    
    	/**
    	 * Executes the defined functions in order.
    	 *
    	 * @param {*} data
    	 * @return {Promise}
    	 */
    	run(data) {;
    		if (this[internalSymbol].queue.isEmpty()) {
    			return Promise.resolve(data);
    		}
    
    		const callback = this[internalSymbol].queue.poll();
    
    		if (callback === null || callback === undefined) {
    			return Promise.resolve(data);
    		}
    
    		return callback.run(data).then((result) => {
    			return this.run(result);
    		});
    	}
    }