"use strict"; const defaultValue = require("default-value"); const { validateOptions, required, isFunction, isNumber } = require("validatem"); module.exports = function createTimer(defaults = {}) { /* TODO: Have a base 'optionsSchema' that's used both here and in `start` via merge-by-template */ validateOptions(arguments, { timeout: [ required, isNumber ], onFire: [ required, isFunction ], onCancel: [ isFunction ] }); let currentTimer; let currentOnCancel = defaults.onCancel; return { stop: function () { if (this.isRunning()) { clearTimeout(currentTimer); currentTimer = null; if (currentOnCancel != null) { currentOnCancel(); } } }, start: function (override = {}) { validateOptions(arguments, { timeout: [ isNumber ], onFire: [ isFunction ], onCancel: [ isFunction ] }); this.stop(); let effectiveTimeout = defaultValue(override.timeout, defaults.timeout); let effectiveOnFire = defaultValue(override.onFire, defaults.onFire); currentOnCancel = defaultValue(override.onCancel, defaults.onCancel); currentTimer = setTimeout(() => { currentTimer = null; effectiveOnFire(); }, effectiveTimeout); }, isRunning: function () { return (currentTimer != null); } }; };