/** * Copyright schukai GmbH and contributors 2022. 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 {isInteger} from "../types/is.mjs"; import {validateFunction, validateInteger} from "../types/validate.mjs"; export {DeadMansSwitch} /** * The dead man's switch allows to set a timer which can be reset again and again within a defined period of time. * * ``` * <script type="module"> * import {DeadMansSwitch} from '@schukai/monster/source/util/deadmansswitch.mjs'; * new DeadMansSwitch(); * </script> * ``` * * @example * import {DeadMansSwitch} from '@schukai/monster/source/util/deadmansswitch.mjs'; * * const deadmansswitch = new DeadMansSwitch(100, ()=>{ * console.log('yeah!') * // ↦ "yeah!" * }) * * deadmansswitch.touch(); // from here wait again 100 ms * deadmansswitch.touch(200); // from here wait 200 ms * * @copyright schukai GmbH * @license AGPLv3 * @since 1.29.0 * @memberOf Monster.Util * @summary Class to be able to execute function chains */ class DeadMansSwitch extends Base { /** * Create new dead man's switch * * @param {Integer} delay * @param {function} callback * @throw {TypeError} the arguments must be either integer or functions * @throws {TypeError} value is not an integer */ constructor(delay, callback) { super(); init.call(this, validateInteger(delay), validateFunction(callback)); } /** * * @param {Integer|undefined} [delay] */ touch(delay) { if (this[internalSymbol]['isAlreadyRun'] === true) { throw new Error('has already run') } if (isInteger(delay)) { this[internalSymbol]['delay'] = delay } else if (delay !== undefined) { throw new Error('unsupported argument') } clearTimeout(this[internalSymbol]['timer']); initCallback.call(this); return this; } } /** * @private */ function initCallback() { const self = this; self[internalSymbol]['timer'] = setTimeout(() => { self[internalSymbol]['isAlreadyRun'] = true; self[internalSymbol]['callback'](); }, self[internalSymbol]['delay']) } /** * @private * @param {integer} delay * @param {function} callback */ function init(delay, callback) { const self = this; self[internalSymbol] = { callback, delay, isAlreadyRun: false, timer: undefined }; initCallback.call(self); }