UNPKG

express-post-task-scheduler

Version:

A lightweight npm package to create and manage scheduled tasks using Express middleware. Configure tasks via POST requests and execute them at specified times seamlessly.

213 lines (212 loc) 6.91 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DB = void 0; const filter_1 = require("./filter"); const tasks_1 = require("../tasks"); const scheduler_1 = require("../scheduler"); const scheduleJobs_1 = require("../scheduleJobs"); const client_1 = require("@prisma/client"); /** * CRUD tasks in the sqlite db file */ class DB { /** * Create or get exist instance of this class */ static init() { if (DB.instance === undefined) { const db = new DB(); db.conn = new client_1.PrismaClient(); DB.instance = db; } return DB.instance; } /** * Restore unfinished tasks from database if the program was terminated */ async loadUnfinshedTasks() { const unfinishedTasks = await this.conn?.taskList.findMany({ where: { executeTime: { gte: new Date(), }, startTime: null, finishTime: null, }, }); if (unfinishedTasks && unfinishedTasks.length > 0) { for (const task of unfinishedTasks) { const executor = tasks_1.tasks.find((_task) => _task.taskName === task.taskName)?.executor; if (executor) { (0, scheduler_1.scheduleTask)(task.executeTime, JSON.parse(task.data), executor, task.id); } } } } /** * Write a new task info into the database * @param taskName For example: Count * @param taskDescription For example: Execute 3 arrow functions to print Count + index on the terminal * @param executeTime The returned formatted datetime string from scheduleTask, for example: "2024-12-30 17:00:00" */ async createTask(taskName, taskDescription, executeTime, data) { const newTask = await this.conn.taskList.create({ data: { taskName, taskDescription, executeTime: new Date(executeTime), data, }, }); return newTask; } /** * Mark a executing task as started * @param taskId The created task's id of method createTask */ async startTask(taskId) { await this.conn.taskList.update({ where: { id: taskId, }, data: { startTime: new Date(), }, }); } /** * Mark a executed task as finished * @param taskId The created task's id of method createTask */ async finishTask(taskId) { await this.conn.taskList.update({ where: { id: taskId, }, data: { finishTime: new Date(), }, }); } /** * Executing a task item successfully * @param taskId The primary key of a task * @param itemId The id of each item in the request body's data field * @param itemValue The stringified value of the item */ async markItemSuccessful(taskId, itemId, itemValue) { await this.conn.$executeRaw(client_1.Prisma.sql ` INSERT INTO Records (itemId, taskId, itemValue, finishTime) VALUES (${itemId}, ${taskId}, ${itemValue}, ${Date.now()}); `); } /** * Executing a task item failed * @param taskId The primary key of a task * @param itemId The id of each item in the request body's data field * @param itemValue The stringified value of the item */ async markItemFailed(taskId, itemId, itemValue, errorMessage) { await this.conn.$executeRaw(client_1.Prisma.sql ` INSERT INTO Records (itemId, taskId, itemValue, error, finishTime) VALUES (${itemId}, ${taskId}, ${itemValue}, ${errorMessage}, ${Date.now()}); `); } /** * To filter the task from database * @param filter The object consist of conditions, the example below shows the tasks finished during 2025-01-02 * @example {"finish": {"after": "2025-01-02", "before": "2025-01-03"}} */ async getTasks(filter) { const conditions = (0, filter_1.getTasksQueryConditions)(filter); const rows = await this.conn.taskList.findMany({ where: { ...conditions, }, select: { id: true, taskName: true, taskDescription: true, executeTime: true, startTime: true, finishTime: true, }, }); return rows; } /** * To delete the task and all related records * @param taskId Primary key of a task record */ async deleteTaskById(taskId) { return this.conn?.taskList.deleteMany({ where: { id: taskId, }, }); } /** * To reschedule waiting state task * @param taskId Primary key of a task record * @param executeTime The new executeTime for reschedule task * @returns */ async rescheduleTask(taskId, executeTime) { let isSuccessful = false; const updatedTask = await this.conn.taskList.update({ where: { id: taskId, }, data: { executeTime, }, select: { id: true, taskName: true, taskDescription: true, executeTime: true, startTime: true, finishTime: true, }, }); if (updatedTask) { const jobs = scheduleJobs_1.ScheduleJobs.init(); const rescheduleJob = jobs.jobList.find((job) => job.taskId === taskId); isSuccessful = rescheduleJob?.jobInstance.reschedule(executeTime) === true; } return { isSuccessful, updatedTask, }; } /** * To filter the records from database * @param filter The object consist of conditions, the example below shows the records finished during 2025-01-02 * @example {"finish": {"after": "2025-01-02", "before": "2025-01-03"}} */ async getRecords(filter) { const conditions = (0, filter_1.getRecordQueryConditions)(filter); const rows = await this.conn.records.findMany({ where: { ...conditions, }, select: { id: true, error: true, finishTime: true, itemId: true, itemValue: true, task: { select: { id: true, taskName: true, taskDescription: true, }, }, }, }); return rows; } } exports.DB = DB;