downtimer
Version:
Timeouts, but a little more relaxing
147 lines • 8.27 kB
JavaScript
"use strict";
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var _Downtimer_instances, _Downtimer_options, _Downtimer_timers, _Downtimer_colors, _Downtimer_onTimer, _Downtimer_onExit;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Downtimer = void 0;
exports.downtimer = downtimer;
const options_1 = require("./options");
const uuid_1 = require("uuid");
const log_1 = require("./log");
const stackTrace_1 = require("./stackTrace");
const colors_1 = __importDefault(require("./colors"));
/** The Downtimer class, which acts as a timer manager */
class Downtimer {
/**
* Create a new Downtimer manager object.
*
* Importantly, this manager can only access timers that it scheduled. As such, creating a new
* `downtimer` object elsewhere in your code won't allow you to clear timers scheduled using a
* different timer manager. As such, it may be best to create a single global `downtimer` manager
* which you use across your entire codebase.
*
* @param options Options for the `Downtimer` object, including settings for logging.
*/
constructor(options = {}) {
_Downtimer_instances.add(this);
/** Options for the manager */
_Downtimer_options.set(this, void 0);
/** Internal mapping of timers */
_Downtimer_timers.set(this, void 0);
/** Color options */
_Downtimer_colors.set(this, void 0);
__classPrivateFieldSet(this, _Downtimer_options, (0, options_1.mergeDeepPartial)(options_1.defaultOptions, options), "f");
__classPrivateFieldSet(this, _Downtimer_timers, {}, "f");
__classPrivateFieldSet(this, _Downtimer_colors, (0, colors_1.default)(__classPrivateFieldGet(this, _Downtimer_options, "f").useColor), "f");
process.on('exit', code => __classPrivateFieldGet(this, _Downtimer_instances, "m", _Downtimer_onExit).call(this, code));
}
/**
* Schedule a callback function to be executed after the given amount of time has elapsed. This
* function returns immediately, meaning that the scheduled callback will be executed after any
* following code.
*
* @param callback callback function to schedule
* @param ms amount of time to wait before calling the callback.
*
* @returns a timer ID which can be used to cancel the scheduled timer. You should store this
* timer ID somewhere in your data structures if there is a chance that you'll need to cancel it
* later.
*/
schedule(callback, ms) {
const externalId = (0, uuid_1.v4)();
const internalId = setTimeout(() => __classPrivateFieldGet(this, _Downtimer_instances, "m", _Downtimer_onTimer).call(this, externalId), ms);
const scheduleStackTrace = (0, stackTrace_1.getStackTrace)();
const options = {
callback,
scheduledAt: Date.now(),
scheduledFor: Date.now() + ms,
externalId,
internalId,
scheduleStackTrace,
};
__classPrivateFieldGet(this, _Downtimer_timers, "f")[externalId] = options;
(0, log_1.logSchedule)(__classPrivateFieldGet(this, _Downtimer_options, "f").logConfig.schedule, options, __classPrivateFieldGet(this, _Downtimer_colors, "f"));
return externalId;
}
/**
* Cancel the scheduled callback function associated with the given timer ID. If the callback
* hasn't been run yet, it will be cancelled and will never run.
*
* If the scheduled callback has already been run, or does not exist, a warning will be logged to
* the console. Importantly, no exception will be thrown.
*
* Note that the scheduled timer must be cancelled using the `downtimer` manager that scheduled
* it. Other `downtimer` manager instances will log a "timer not found" warning.
*
* @param timerId ID of timer to clear
*/
clear(timerId) {
const timer = __classPrivateFieldGet(this, _Downtimer_timers, "f")[timerId];
if (!timer) {
(0, log_1.logClearNotFound)(__classPrivateFieldGet(this, _Downtimer_options, "f").logConfig.clear.notFound, timerId, __classPrivateFieldGet(this, _Downtimer_colors, "f"));
return;
}
(0, log_1.logClearSuccess)(__classPrivateFieldGet(this, _Downtimer_options, "f").logConfig.clear.success, timer, __classPrivateFieldGet(this, _Downtimer_colors, "f"));
clearTimeout(timer.internalId);
delete __classPrivateFieldGet(this, _Downtimer_timers, "f")[timerId];
}
/**
* Cancel all outstanding callback functions.
*
* This cancels all scheduled timers managed by this `downtimer` object. Note that timers
* scheduled by other `downtimer` manager objects won't be cleared.
*/
clearAll() {
(0, log_1.logClearAll)(__classPrivateFieldGet(this, _Downtimer_options, "f").logConfig.clear.allOutstanding, __classPrivateFieldGet(this, _Downtimer_timers, "f"), __classPrivateFieldGet(this, _Downtimer_colors, "f"));
for (const [_timerId, timer] of Object.entries(__classPrivateFieldGet(this, _Downtimer_timers, "f"))) {
clearTimeout(timer.internalId);
}
__classPrivateFieldSet(this, _Downtimer_timers, {}, "f");
}
}
exports.Downtimer = Downtimer;
_Downtimer_options = new WeakMap(), _Downtimer_timers = new WeakMap(), _Downtimer_colors = new WeakMap(), _Downtimer_instances = new WeakSet(), _Downtimer_onTimer = function _Downtimer_onTimer(timerId) {
const timer = __classPrivateFieldGet(this, _Downtimer_timers, "f")[timerId];
if (!timer) {
return;
}
(0, log_1.logBeforeExecute)(__classPrivateFieldGet(this, _Downtimer_options, "f").logConfig.execute.before, timer, __classPrivateFieldGet(this, _Downtimer_colors, "f"));
delete __classPrivateFieldGet(this, _Downtimer_timers, "f")[timerId];
try {
timer.callback();
}
catch (e) {
(0, log_1.logErrorInExecute)(__classPrivateFieldGet(this, _Downtimer_options, "f").logConfig.execute.onError, timer, e, __classPrivateFieldGet(this, _Downtimer_colors, "f"));
}
}, _Downtimer_onExit = function _Downtimer_onExit(code) {
if (Object.keys(__classPrivateFieldGet(this, _Downtimer_timers, "f")).length) {
(0, log_1.logClearOnExit)(__classPrivateFieldGet(this, _Downtimer_options, "f").logConfig.exitWithOutstandingTimers, __classPrivateFieldGet(this, _Downtimer_timers, "f"), code, __classPrivateFieldGet(this, _Downtimer_colors, "f"));
this.clearAll();
}
};
/**
* Create a new Downtimer manager object.
*
* Importantly, this manager can only access timers that it scheduled. As such, creating a new
* `downtimer` object elsewhere in your code won't allow you to clear timers scheduled using a
* different timer manager. As such, it may be best to create a single global `downtimer` manager
* which you use across your entire codebase.
*
* @param options Options for the `Downtimer` object, including settings for logging.
*/
function downtimer(options = {}) {
return new Downtimer(options);
}
//# sourceMappingURL=downtimer.js.map