@stacksjs/scheduler 0.68.2 → 0.69.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/run.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ import type { Err } from '@stacksjs/error-handling';
2
+ import type { JobOptions } from '@stacksjs/types';
3
+
4
+ export declare function runScheduler(): Promise<Ok<string, never> | Err<string, any>>;
5
+ declare function runSchedulerInstance(): Promise<void>;
6
+ declare function executeJobRate(jobName: string, rate: string): void;
7
+ declare function getJobName(job: JobOptions, jobPath: string): string;
@@ -1,131 +1,239 @@
1
- import type { DateTime } from 'luxon';
1
+ import type { CatchCallbackFn, CronOptions } from '@stacksjs/cron';
2
+ import type { TimedSchedule, Timezone, UntimedSchedule } from './types';
2
3
 
3
- export declare class Schedule {
4
+ export declare class Schedule implements UntimedSchedule {
5
+ private static jobs = new Map<string, Cron>()
4
6
  private cronPattern = ''
5
- private timezone = 'America/Los_Angeles'
7
+ private timezone: Timezone = 'America/Los_Angeles'
6
8
  private readonly task: () => void
9
+ private options: {
10
+ timezone?: string
11
+ catch?: CatchCallbackFn
12
+ maxRuns?: number
13
+ protect?: boolean | ((job: Cron) => void)
14
+ name?: string
15
+ context?: any
16
+ interval?: number
17
+ startAt?: string | Date
18
+ stopAt?: string | Date
19
+ } = {}
7
20
 
8
21
  constructor(task: () => void) {
9
22
  this.task = task
23
+ setTimeout(() => this.start(), 0)
10
24
  }
11
25
 
12
- everySecond(): Schedule {
26
+ everySecond(): TimedSchedule {
13
27
  this.cronPattern = '* * * * * *'
14
- return this
28
+ return this as TimedSchedule
15
29
  }
16
30
 
17
- everyMinute(): Schedule {
31
+ everyMinute(): TimedSchedule {
18
32
  this.cronPattern = '0 * * * * *'
19
- return this
33
+ return this as TimedSchedule
20
34
  }
21
35
 
22
- everyTwoMinutes(): Schedule {
36
+ everyTwoMinutes(): TimedSchedule {
23
37
  this.cronPattern = '*/2 * * * * *'
24
- return this
38
+ return this as TimedSchedule
25
39
  }
26
40
 
27
- everyFiveMinutes(): Schedule {
41
+ everyFiveMinutes(): TimedSchedule {
28
42
  this.cronPattern = '*/5 * * * *'
29
- return this
43
+ return this as TimedSchedule
30
44
  }
31
45
 
32
- everyTenMinutes(): Schedule {
46
+ everyTenMinutes(): TimedSchedule {
33
47
  this.cronPattern = '*/10 * * * *'
34
- return this
48
+ return this as TimedSchedule
35
49
  }
36
50
 
37
- everyThirtyMinutes(): Schedule {
51
+ everyThirtyMinutes(): TimedSchedule {
38
52
  this.cronPattern = '*/30 * * * *'
39
- return this
53
+ return this as TimedSchedule
40
54
  }
41
55
 
42
- everyHour(): Schedule {
56
+ everyHour(): TimedSchedule {
43
57
  this.cronPattern = '0 0 * * * *'
44
- return this
58
+ return this as TimedSchedule
45
59
  }
46
60
 
47
- everyDay(): Schedule {
61
+ everyDay(): TimedSchedule {
48
62
  this.cronPattern = '0 0 0 * * *'
49
- return this
63
+ return this as TimedSchedule
50
64
  }
51
65
 
52
- hourly(): Schedule {
66
+ hourly(): TimedSchedule {
53
67
  this.cronPattern = '0 0 * * * *'
54
- return this
68
+ return this as TimedSchedule
55
69
  }
56
70
 
57
- daily(): Schedule {
71
+ daily(): TimedSchedule {
58
72
  this.cronPattern = '0 0 0 * * *'
59
- return this
73
+ return this as TimedSchedule
60
74
  }
61
75
 
62
- weekly(): Schedule {
76
+ weekly(): TimedSchedule {
63
77
  this.cronPattern = '0 0 0 * * 0'
64
- return this
78
+ return this as TimedSchedule
65
79
  }
66
80
 
67
- monthly(): Schedule {
81
+ monthly(): TimedSchedule {
68
82
  this.cronPattern = '0 0 0 1 * *'
69
- return this
83
+ return this as TimedSchedule
70
84
  }
71
85
 
72
- yearly(): Schedule {
86
+ yearly(): TimedSchedule {
73
87
  this.cronPattern = '0 0 0 1 1 *'
74
- return this
88
+ return this as TimedSchedule
75
89
  }
76
90
 
77
- onDays(days: number[]): Schedule {
91
+ annually(): TimedSchedule {
92
+ this.cronPattern = '0 0 0 1 1 *'
93
+ return this as TimedSchedule
94
+ }
95
+
96
+ onDays(days: number[]): TimedSchedule {
78
97
  const dayPattern = days.join(',')
79
98
  this.cronPattern = `0 0 0 * * ${dayPattern}`
80
- return this
99
+ return this as TimedSchedule
81
100
  }
82
101
 
83
-
84
- at(time: string): Schedule {
102
+ at(time: string): TimedSchedule {
85
103
  const [hour, minute] = time.split(':').map(Number)
86
104
  this.cronPattern = `${minute} ${hour} * * *`
87
- return this
105
+ return this as TimedSchedule
88
106
  }
89
107
 
90
- setTimeZone(timezone: string): Schedule {
108
+ setTimeZone(timezone: Timezone): this {
91
109
  this.timezone = timezone
110
+ this.options.timezone = timezone
92
111
  return this
93
112
  }
94
113
 
95
- start(): void {
96
- new CronJob(this.cronPattern, this.task, null, true, this.timezone)
97
- log.info(`Scheduled task with pattern: ${this.cronPattern} in timezone: ${this.timezone}`)
114
+ withErrorHandler(handler: CatchCallbackFn): this {
115
+ this.options.catch = handler
116
+ return this
117
+ }
118
+
119
+ withMaxRuns(runs: number): this {
120
+ this.options.maxRuns = runs
121
+ return this
122
+ }
123
+
124
+ withProtection(callback?: (job: Cron) => void): this {
125
+ this.options.protect = callback || true
126
+ return this
127
+ }
128
+
129
+ withName(name: string): this {
130
+ this.options.name = name
131
+ return this
132
+ }
133
+
134
+ withContext(context: any): this {
135
+ this.options.context = context
136
+ return this
98
137
  }
99
138
 
100
- job(path: string): Schedule {
101
- log.info(`Scheduling job: ${path}`)
139
+ withInterval(seconds: number): this {
140
+ this.options.interval = seconds
102
141
  return this
103
142
  }
104
143
 
105
- action(path: string): Schedule {
106
- log.info(`Scheduling action: ${path}`)
144
+ between(startAt: string | Date, stopAt: string | Date): this {
145
+ this.options.startAt = startAt
146
+ this.options.stopAt = stopAt
107
147
  return this
108
148
  }
109
149
 
110
- static command(cmd: string): Schedule {
111
- log.info(`Executing command: ${cmd}`)
150
+ private start(): Cron {
151
+ const job = new Cron(
152
+ this.cronPattern,
153
+ {
154
+ ...this.options,
155
+ timezone: this.timezone,
156
+ } as CronOptions,
157
+ this.task,
158
+ )
159
+
160
+ if (this.options.name) {
161
+ Schedule.jobs.set(this.options.name, job)
162
+ }
163
+
164
+ log.info(`Scheduled task with pattern: ${this.cronPattern} in timezone: ${this.timezone}`)
165
+ return job
166
+ }
167
+
168
+ static job(name: string): UntimedSchedule {
112
169
  return new Schedule(async () => {
113
- log.info(`Executing command: ${cmd}`)
170
+ log.info(`Running job: ${name}`)
171
+ try {
172
+ await runJob(name)
173
+ }
174
+ catch (error) {
175
+ log.error(`Job ${name} failed:`, error)
176
+ throw error
177
+ }
178
+ }).withName(name) as UntimedSchedule
179
+ }
114
180
 
115
- const result = await runCommand(cmd)
181
+ static action(name: string): UntimedSchedule {
182
+ return new Schedule(async () => {
183
+ log.info(`Running action: ${name}`)
184
+ try {
185
+ await runAction(name)
186
+ }
187
+ catch (error) {
188
+ log.error(`Action ${name} failed:`, error)
189
+ throw error
190
+ }
191
+ }).withName(name) as UntimedSchedule
192
+ }
116
193
 
117
- if (result.isErr()) {
118
- log.error(result.error)
119
- return
194
+ static command(cmd: string): UntimedSchedule {
195
+ return new Schedule(async () => {
196
+ try {
197
+ log.info(`Executing command: ${cmd}`)
198
+ const result = await runCommand(cmd)
199
+
200
+ if (result.isErr()) {
201
+ log.error(result.error)
202
+ throw result.error
203
+ }
120
204
  }
205
+ catch (error) {
206
+ log.error(`Command execution failed: ${error}`)
207
+ throw error
208
+ }
209
+ }).withName(`command-${cmd}`) as UntimedSchedule
210
+ }
211
+
212
+ static async gracefulShutdown(): Promise<void> {
213
+ log.info('Gracefully shutting down scheduled jobs...')
214
+
215
+ const shutdownPromises = []
216
+
217
+ for (const [name, job] of Schedule.jobs) {
218
+ log.info(`Stopping job: ${name}`)
219
+ shutdownPromises.push(
220
+ new Promise<void>((resolve) => {
221
+ job.stop()
222
+ resolve()
223
+ }),
224
+ )
225
+ }
226
+
227
+ await Promise.all(shutdownPromises)
228
+ Schedule.jobs.clear()
121
229
 
122
- log.info(result.value)
123
- })
230
+ log.info('All jobs have been stopped')
124
231
  }
125
232
  }
126
- export declare class Job extends Schedule {}
127
- export declare function sendAt(cronTime: string | Date | DateTime): DateTime;
128
- export declare function timeout(cronTime: string | Date | DateTime): number;
233
+ export declare class Job extends Schedule { }
234
+ export declare function sendAt(cronTime: string | Date): Date | null;
235
+ export declare function timeout(cronTime: string | Date): number;
129
236
  export declare type Scheduler = typeof Schedule
237
+ export const schedule: Scheduler = Schedule
130
238
 
131
- export default Schedule;
239
+ export default Schedule
package/dist/types.d.ts CHANGED
@@ -1,3 +1,101 @@
1
- export declare type IntRange<Min extends number, Max extends number> = number extends Min | Max
2
- ? never
3
- : number | [Min | number, Max | number]
1
+ import type { CatchCallbackFn, Cron } from '@stacksjs/cron';
2
+
3
+ export declare type Timezone =
4
+ | 'Africa/Abidjan'
5
+ | 'Africa/Accra'
6
+ | 'Africa/Addis_Ababa'
7
+ | 'Africa/Algiers'
8
+ | 'Africa/Cairo'
9
+ | 'Africa/Casablanca'
10
+ | 'Africa/Lagos'
11
+ | 'Africa/Nairobi'
12
+ | 'America/Anchorage'
13
+ | 'America/Argentina/Buenos_Aires'
14
+ | 'America/Bogota'
15
+ | 'America/Caracas'
16
+ | 'America/Chicago'
17
+ | 'America/Denver'
18
+ | 'America/Detroit'
19
+ | 'America/Halifax'
20
+ | 'America/Los_Angeles'
21
+ | 'America/Mexico_City'
22
+ | 'America/New_York'
23
+ | 'America/Phoenix'
24
+ | 'America/Santiago'
25
+ | 'America/Sao_Paulo'
26
+ | 'America/Toronto'
27
+ | 'America/Vancouver'
28
+ | 'Asia/Bangkok'
29
+ | 'Asia/Dubai'
30
+ | 'Asia/Hong_Kong'
31
+ | 'Asia/Istanbul'
32
+ | 'Asia/Jakarta'
33
+ | 'Asia/Jerusalem'
34
+ | 'Asia/Karachi'
35
+ | 'Asia/Kolkata'
36
+ | 'Asia/Kuwait'
37
+ | 'Asia/Manila'
38
+ | 'Asia/Shanghai'
39
+ | 'Asia/Singapore'
40
+ | 'Asia/Tokyo'
41
+ | 'Australia/Melbourne'
42
+ | 'Australia/Perth'
43
+ | 'Australia/Sydney'
44
+ | 'Europe/Amsterdam'
45
+ | 'Europe/Athens'
46
+ | 'Europe/Belgrade'
47
+ | 'Europe/Berlin'
48
+ | 'Europe/Brussels'
49
+ | 'Europe/Budapest'
50
+ | 'Europe/Copenhagen'
51
+ | 'Europe/Dublin'
52
+ | 'Europe/Helsinki'
53
+ | 'Europe/Istanbul'
54
+ | 'Europe/Lisbon'
55
+ | 'Europe/London'
56
+ | 'Europe/Madrid'
57
+ | 'Europe/Moscow'
58
+ | 'Europe/Paris'
59
+ | 'Europe/Prague'
60
+ | 'Europe/Rome'
61
+ | 'Europe/Stockholm'
62
+ | 'Europe/Vienna'
63
+ | 'Europe/Warsaw'
64
+ | 'Europe/Zurich'
65
+ | 'Pacific/Auckland'
66
+ | 'Pacific/Fiji'
67
+ | 'Pacific/Honolulu'
68
+ | 'UTC'
69
+
70
+ export interface BaseSchedule {
71
+ withErrorHandler: (handler: CatchCallbackFn) => this
72
+ withMaxRuns: (runs: number) => this
73
+ withProtection: (callback?: (job: Cron) => void) => this
74
+ withName: (name: string) => this
75
+ withContext: (context: any) => this
76
+ withInterval: (seconds: number) => this
77
+ between: (startAt: string | Date, stopAt: string | Date) => this
78
+ setTimeZone: (timezone: Timezone) => this
79
+ }
80
+
81
+ export interface TimedSchedule extends BaseSchedule {
82
+ }
83
+
84
+ export interface UntimedSchedule extends BaseSchedule {
85
+ everySecond: () => TimedSchedule
86
+ everyMinute: () => TimedSchedule
87
+ everyTwoMinutes: () => TimedSchedule
88
+ everyFiveMinutes: () => TimedSchedule
89
+ everyTenMinutes: () => TimedSchedule
90
+ everyThirtyMinutes: () => TimedSchedule
91
+ everyHour: () => TimedSchedule
92
+ everyDay: () => TimedSchedule
93
+ hourly: () => TimedSchedule
94
+ daily: () => TimedSchedule
95
+ weekly: () => TimedSchedule
96
+ monthly: () => TimedSchedule
97
+ yearly: () => TimedSchedule
98
+ annually: () => TimedSchedule
99
+ onDays: (days: number[]) => TimedSchedule
100
+ at: (time: string) => TimedSchedule
101
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stacksjs/scheduler",
3
3
  "type": "module",
4
- "version": "0.68.2",
4
+ "version": "0.69.2",
5
5
  "description": "The Stacks scheduler.",
6
6
  "author": "Chris Breuer",
7
7
  "contributors": ["Chris Breuer <chris@stacksjs.org>"],
@@ -33,10 +33,9 @@
33
33
  "typecheck": "bun tsc --noEmit",
34
34
  "prepublishOnly": "bun run build"
35
35
  },
36
- "dependencies": {
37
- "cron": "^3.1.7"
38
- },
39
36
  "devDependencies": {
40
- "@stacksjs/development": "0.68.1"
37
+ "@stacksjs/actions": "0.69.2",
38
+ "@stacksjs/cron": "0.69.2",
39
+ "@stacksjs/development": "0.69.2"
41
40
  }
42
41
  }
package/dist/cron.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export type {;
2
- export { CronJob, CronTime } from 'cron'