Skip to content
Snippets Groups Projects
Select Git revision
  • 026a00a0603b3606a05e55d23bcf12c47d2ee6e5
  • master default protected
  • 1.31
  • 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
  • 4.28.0
  • 4.27.0
  • 4.26.0
  • 4.25.5
  • 4.25.4
  • 4.25.3
  • 4.25.2
  • 4.25.1
23 results

processing.mjs

Blame
  • processing.mjs 4.25 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) {
            const self = this;
            return new Promise((resolve, reject) => {
                getGlobalFunction("setTimeout")(() => {
                    try {
                        resolve(self[internalSymbol].callback(data));
                    } catch (e) {
                        reject(e);
                    }
                }, self[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
         *
         * @param {int} timeout Timeout
         * @param {function} callback Callback
         * @throw {TypeError} the arguments must be either integer or functions
         */
        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) {
            const self = this;
            if (this[internalSymbol].queue.isEmpty()) {
                return Promise.resolve(data);
            }
    
            return this[internalSymbol].queue
                .poll()
                .run(data)
                .then((result) => {
                    return self.run(result);
                });
        }
    }