cron-schedule
Version:
A zero-dependency cron parser and scheduler for Node.js, Deno and the browser.
119 lines • 6.62 kB
JavaScript
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 _IntervalBasedCronScheduler_interval, _IntervalBasedCronScheduler_intervalId, _IntervalBasedCronScheduler_tasks, _IntervalBasedCronScheduler_nextTaskId;
import { wrapFunction } from '../utils.js';
/**
* A cron scheduler that is based on a single interval.
* Every interval, it checks whether a registered cron task
* was due during the last interval and executes it.
* This scheduler might be more performant depending on the use case,
* because it only creates a single interval for all scheduled crons,
* however depending on the interval and crons, tasks might be executed
* with a delay.
*/
export class IntervalBasedCronScheduler {
/**
* Creates and starts a new scheduler with the given interval.
*/
constructor(interval) {
_IntervalBasedCronScheduler_interval.set(this, void 0);
_IntervalBasedCronScheduler_intervalId.set(this, void 0);
_IntervalBasedCronScheduler_tasks.set(this, []);
_IntervalBasedCronScheduler_nextTaskId.set(this, 1
/**
* Creates and starts a new scheduler with the given interval.
*/
);
__classPrivateFieldSet(this, _IntervalBasedCronScheduler_interval, interval, "f");
this.start();
}
/* Starts the scheduler. */
start() {
if (__classPrivateFieldGet(this, _IntervalBasedCronScheduler_intervalId, "f") !== undefined) {
throw new Error('Scheduler already started.');
}
__classPrivateFieldSet(this, _IntervalBasedCronScheduler_intervalId, setInterval(this.processTasks.bind(this), __classPrivateFieldGet(this, _IntervalBasedCronScheduler_interval, "f")), "f");
}
/* Ensures the scheduler is stopped. */
stop() {
if (__classPrivateFieldGet(this, _IntervalBasedCronScheduler_intervalId, "f")) {
clearInterval(__classPrivateFieldGet(this, _IntervalBasedCronScheduler_intervalId, "f"));
__classPrivateFieldSet(this, _IntervalBasedCronScheduler_intervalId, undefined, "f");
}
}
/* Inserts a task in the tasks array at the right position sorted by nextExecution time. */
insertTask(newTask) {
const index = __classPrivateFieldGet(this, _IntervalBasedCronScheduler_tasks, "f").findIndex((task) => task.nextExecution.getTime() > newTask.nextExecution.getTime());
__classPrivateFieldGet(this, _IntervalBasedCronScheduler_tasks, "f").splice(index, 0, newTask);
}
/* Registers a new task. */
registerTask(cron, task, opts) {
var _a;
const id = __classPrivateFieldGet(this, _IntervalBasedCronScheduler_nextTaskId, "f");
this.insertTask({
id,
cron,
nextExecution: cron.getNextDate(),
task,
isOneTimeTask: (_a = opts === null || opts === void 0 ? void 0 : opts.isOneTimeTask) !== null && _a !== void 0 ? _a : false,
errorHandler: opts === null || opts === void 0 ? void 0 : opts.errorHandler,
});
__classPrivateFieldSet(this, _IntervalBasedCronScheduler_nextTaskId, __classPrivateFieldGet(this, _IntervalBasedCronScheduler_nextTaskId, "f") + 1, "f");
return id;
}
/** Unregisters a task, causing it to no longer be executed. */
unregisterTask(id) {
const taskIndex = __classPrivateFieldGet(this, _IntervalBasedCronScheduler_tasks, "f").findIndex((task) => task.id === id);
if (taskIndex === -1)
throw new Error('Task not found.');
__classPrivateFieldGet(this, _IntervalBasedCronScheduler_tasks, "f").splice(taskIndex, 1);
}
/* Sorts the tasks array based on the next execution time so that the next task is first in the array. */
sortTasks() {
__classPrivateFieldGet(this, _IntervalBasedCronScheduler_tasks, "f").sort((a, b) => {
return a.nextExecution.getTime() - b.nextExecution.getTime();
});
}
processTasks() {
const now = Date.now();
let taskExecuted = false;
let oneTimeTaskExecuted = false;
// Execute all due tasks and update nextExecution for non-one-time tasks.
for (let i = 0; i < __classPrivateFieldGet(this, _IntervalBasedCronScheduler_tasks, "f").length; i += 1) {
const task = __classPrivateFieldGet(this, _IntervalBasedCronScheduler_tasks, "f")[i];
if (task.nextExecution.getTime() <= now) {
wrapFunction(task.task, task.errorHandler)();
if (!task.isOneTimeTask) {
taskExecuted = true;
task.nextExecution = task.cron.getNextDate();
}
else {
oneTimeTaskExecuted = true;
}
}
else {
break;
}
}
if (oneTimeTaskExecuted) {
// Remove one time tasks.
__classPrivateFieldSet(this, _IntervalBasedCronScheduler_tasks, __classPrivateFieldGet(this, _IntervalBasedCronScheduler_tasks, "f").filter((task) => task.nextExecution.getTime() > now), "f");
}
// When at least one nextExecution time got updated (at least one non-one-time-task ran),
// we need to resort the tasks based on nextExecution.
if (taskExecuted) {
this.sortTasks();
}
}
}
_IntervalBasedCronScheduler_interval = new WeakMap(), _IntervalBasedCronScheduler_intervalId = new WeakMap(), _IntervalBasedCronScheduler_tasks = new WeakMap(), _IntervalBasedCronScheduler_nextTaskId = new WeakMap();
//# sourceMappingURL=interval-based.js.map