diff --git a/README.md b/README.md index 4896eec..42e0fc2 100644 --- a/README.md +++ b/README.md @@ -39,16 +39,20 @@ $ npm i --save nest-schedule ```typescript import { Injectable } from '@nestjs/common'; -import { Schedule } from 'nest-schedule'; +import { Schedule, NestSchedule } from 'nest-schedule'; @Injectable() -export class ScheduleService { +export class ScheduleService extends NestSchedule { + constructor() { + super(); + } + @Schedule({ cron: '0 0 2 * *', startTime: new Date(), endTime: new Date(new Date().getTime() + 24 * 60 * 60 * 1000) }) - syncData() { + async syncData() { console.log('syncing data ...'); } @@ -67,7 +71,7 @@ export class ScheduleService { intervalJob() { console.log('interval job'); - // if you want to cancel the schedule job, you should return true; + // if you want to cancel the job, you should return true; return true; } } diff --git a/lib/NestSchedule.ts b/lib/NestSchedule.ts new file mode 100644 index 0000000..954db8a --- /dev/null +++ b/lib/NestSchedule.ts @@ -0,0 +1,58 @@ +import { NEST_SCHEDULE_JOB_KEY } from "./constants"; +import * as schedule from "node-schedule"; + +export class NestSchedule { + private readonly jobs; + private readonly timers = {}; + + constructor() { + this.jobs = Reflect.getMetadata(NEST_SCHEDULE_JOB_KEY, new.target.prototype); + this.init(); + } + + private init() { + if (this.jobs) { + this.jobs.forEach(job => { + if (job.cron) { + job = schedule.scheduleJob({ + startTime: job.startTime, + endTime: job.endTime, + rule: job.cron + }, async () => { + let result = this[job.key](); + if (result instanceof Promise) { + result = await result; + } + if (result && job) { + job.cancel(); + } + }); + } + if (job.interval) { + this.timers[job.key] = setInterval(async () => { + let result = this[job.key](); + if (result instanceof Promise) { + result = await result; + } + if (result && this.timers[job.key]) { + clearInterval(this.timers[job.key]); + delete this.timers[job.key]; + } + }, job.interval); + } + if (job.timeout) { + this.timers[job.key] = setTimeout(async () => { + let result = this[job.key](); + if (result instanceof Promise) { + result = await result; + } + if (result && this.timers[job.key]) { + clearTimeout(this.timers[job.key]); + delete this.timers[job.key]; + } + }, job.timeout); + } + }); + } + } +} \ No newline at end of file diff --git a/lib/Schedule.ts b/lib/Schedule.ts new file mode 100644 index 0000000..e00f387 --- /dev/null +++ b/lib/Schedule.ts @@ -0,0 +1,20 @@ +import "reflect-metadata"; +import { NEST_SCHEDULE_JOB_KEY } from "./constants"; + +export interface Options { + cron?: string; + interval?: number; + timeout?: number; + startTime?: Date; + endTime?: Date; +} + +export const Schedule = (options: Options) => (target, key, descriptor) => { + let jobs = Reflect.getMetadata(NEST_SCHEDULE_JOB_KEY, target); + if (!jobs) { + jobs = []; + } + + jobs.push({ ...options, key }); + Reflect.defineMetadata(NEST_SCHEDULE_JOB_KEY, jobs, target); +}; \ No newline at end of file diff --git a/lib/constants.ts b/lib/constants.ts new file mode 100644 index 0000000..7a03d4d --- /dev/null +++ b/lib/constants.ts @@ -0,0 +1 @@ +export const NEST_SCHEDULE_JOB_KEY = "nest_schedule_jobs"; \ No newline at end of file diff --git a/lib/decorators/Schedule.ts b/lib/decorators/Schedule.ts deleted file mode 100644 index 5c13db5..0000000 --- a/lib/decorators/Schedule.ts +++ /dev/null @@ -1,59 +0,0 @@ -import "reflect-metadata"; -import * as schedule from "node-schedule"; - -export class Options { - cron?: string; - interval?: number; - timeout?: number; - startTime?: Date; - endTime?: Date; -} - -export const Schedule = (options: Options) => (target, key, descriptor) => { - const oldValue = descriptor.value; - let job, intervalTimer, timer; - const init = function() { - if (options.cron) { - job = schedule.scheduleJob({ - startTime: options.startTime, - endTime: options.endTime, - rule: options.cron - }, async () => { - let result = oldValue.call(this); - if (result instanceof Promise) { - result = await result; - } - if (result && job) { - job.cancel(); - } - }); - } - if (options.interval) { - intervalTimer = setInterval(async () => { - let result = oldValue.call(this); - if (result instanceof Promise) { - result = await result; - } - if (result && intervalTimer) { - clearInterval(intervalTimer); - intervalTimer = null; - } - }, options.interval); - } - if (options.timeout) { - timer = setTimeout(async () => { - let result = oldValue.call(this); - if (result instanceof Promise) { - result = await result; - } - if (result && timer) { - clearTimeout(timer); - timer = null; - } - }, options.timeout); - } - }; - - init(); - return descriptor; -}; \ No newline at end of file diff --git a/lib/index.ts b/lib/index.ts index 77e517e..053acb4 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -1 +1,3 @@ -export * from "./decorators/Schedule"; \ No newline at end of file +export * from "./Schedule"; +export * from "./NestSchedule"; +export * from "./constants"; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 2002385..597ee55 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "nest-schedule", - "version": "0.1.0", + "version": "0.2.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index a25422c..f090030 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nest-schedule", - "version": "0.1.0", + "version": "0.2.0", "description": "Nest - modern, fast, powerful node.js web framework (@schedule)", "author": "Miaowing ", "license": "MIT",