diff --git a/src/core/modules.ts b/src/core/modules.ts index 8d9d6f19..81ffbabe 100644 --- a/src/core/modules.ts +++ b/src/core/modules.ts @@ -4,6 +4,7 @@ import type { InputCommand, InputEvent, Module, + ScheduledTask, } from '../types/core-modules'; import { partitionPlugins } from './functions' import type { Awaitable } from '../types/utility'; @@ -46,3 +47,8 @@ export function discordEvent(mod: { return eventModule({ type: EventType.Discord, ...mod, }); } + +export function scheduledTask(i : ScheduledTask) { + return i +} + diff --git a/src/core/schedule.ts b/src/core/schedule.ts index fea65c49..966da128 100644 --- a/src/core/schedule.ts +++ b/src/core/schedule.ts @@ -2,16 +2,24 @@ import { CronJob } from 'cron'; export class TaskScheduler { private __tasks: Map = new Map(); - scheduleTask(taskName: string, cronExpression: string, task: () => void): boolean { + scheduleTask(taskName: string, cronExpression: string | Date, task: () => void, tz: string| undefined): boolean { if (this.__tasks.has(taskName)) { + console.warn("While scheduling a task", + "found another task of same name. Not scheduling", + taskName, "again"); return false; } try { - const job = new CronJob(cronExpression, task); + const job = CronJob.from({ + cronTime: cronExpression, + onTick: task, + timeZone: tz + }); job.start(); this.__tasks.set(taskName, job); return true; } catch (error) { + console.error("While scheduling a task " + error); return false; } } diff --git a/src/handlers/ready.ts b/src/handlers/ready.ts index 83f485c5..662b1bd0 100644 --- a/src/handlers/ready.ts +++ b/src/handlers/ready.ts @@ -23,8 +23,8 @@ export default async function(dir: string, deps : UnpackedDependencies) { if(!validType) { throw Error(`Found ${module.name} at ${module.meta.absPath}, which has incorrect \`type\``); } - const resultModule = await callInitPlugins(module, deps, true); // FREEZE! no more writing!! - + const resultModule = await callInitPlugins(module, deps, true); + // FREEZE! no more writing!! commands.set(resultModule.meta.id, Object.freeze(resultModule)); sEmitter.emit('module.register', resultPayload('success', resultModule)); } diff --git a/src/handlers/tasks.ts b/src/handlers/tasks.ts index 441b1cf8..1f5a80f4 100644 --- a/src/handlers/tasks.ts +++ b/src/handlers/tasks.ts @@ -1,23 +1,29 @@ import { TaskScheduler } from "../core/schedule" import * as Files from '../core/module-loading' import { UnpackedDependencies } from "../types/utility"; +import { ScheduledTask } from "../types/core-modules"; +import { CronJob } from "cron"; +import { relative } from "path"; +import { fileURLToPath } from "url"; -interface ScheduledTaskModule { - name?: string; - description?: string; - pattern: string; - execute(deps: UnpackedDependencies, tasks: string[]): any -} - -export const registerTasks = async (path: string, deps: UnpackedDependencies) => { +export const registerTasks = async (tasksPath: string, deps: UnpackedDependencies) => { const taskManager = new TaskScheduler() - for await (const f of Files.readRecursive(path)) { - let { module } = await Files.importModule(f); + for await (const f of Files.readRecursive(tasksPath)) { + let { module } = await Files.importModule(f); + //module.name is assigned by Files.importModule<> - taskManager.scheduleTask(module.name!, module.pattern, () => { - module.execute(deps, taskManager.tasks()) - }) + // the id created for the task is unique + const uuid = module.name!+":"+relative(tasksPath,fileURLToPath(f)) + taskManager.scheduleTask(uuid, module.pattern, function(this: CronJob) { + module.execute({ + deps, + runningTasks: taskManager.tasks(), + lastTimeExecution: this.lastExecution, + nextTimeExecution: this.nextDate().toJSDate() + }) + }, + module.timezone) } } diff --git a/src/index.ts b/src/index.ts index 1667ff98..7de8cdca 100644 --- a/src/index.ts +++ b/src/index.ts @@ -25,7 +25,8 @@ export type { SernOptionsData, SernSubCommandData, SernSubCommandGroupData, - SDT + SDT, + ScheduledTask } from './types/core-modules'; export type { @@ -43,6 +44,7 @@ export { commandModule, eventModule, discordEvent, + scheduledTask } from './core/modules'; export * from './core/presences' diff --git a/src/types/core-modules.ts b/src/types/core-modules.ts index a9bf143b..d8c380b3 100644 --- a/src/types/core-modules.ts +++ b/src/types/core-modules.ts @@ -19,7 +19,7 @@ import type { import type { CommandType, EventType } from '../core/structures/enums'; import { Context } from '../core/structures/context' import { ControlPlugin, InitPlugin, Plugin } from './core-plugin'; -import { Awaitable, SernEventsMapping } from './utility'; +import { Awaitable, SernEventsMapping, UnpackedDependencies } from './utility'; //state, deps, type (very original) export type SDT = { @@ -222,3 +222,21 @@ export interface SernSubCommandGroupData extends BaseApplicationCommandOptionsDa type: ApplicationCommandOptionType.SubcommandGroup; options?: SernSubCommandData[]; } + + +interface ScheduledTaskContext { + deps: UnpackedDependencies, + lastTimeExecution: Date | null; + runningTasks: string[]; + nextTimeExecution: Date | null; +} + +export interface ScheduledTask { + name?: string; + pattern: string | Date; + description?: string; + timezone?: string; + execute(tasks: ScheduledTaskContext): Awaitable +} + +