@stacksjs/scheduler 0.70.22 → 0.70.25

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.
@@ -0,0 +1,4 @@
1
+ // export { Schedule } from './schedule'
2
+ export * from './run';
3
+ export * from './schedule';
4
+ export * from './types';
@@ -0,0 +1,2 @@
1
+ import type { Err, Ok } from '@stacksjs/error-handling';
2
+ export declare function runScheduler(): Promise<Ok<string, never> | Err<string, any>>;
@@ -0,0 +1,73 @@
1
+ import type { CatchCallbackFn } from '@stacksjs/cron';
2
+ import type { ScheduledJob, TimedSchedule, Timezone, UntimedSchedule } from './types';
3
+ /**
4
+ * Get the next run time for a cron expression.
5
+ *
6
+ * @param cronExpression - Standard 5-field cron expression or nickname
7
+ * @returns The next Date the expression matches, or null
8
+ */
9
+ export declare function sendAt(cronExpression: string | Date): Date | null;
10
+ /**
11
+ * Get the number of milliseconds until the next run of a cron expression.
12
+ *
13
+ * @param cronExpression - Standard 5-field cron expression or nickname
14
+ * @returns Milliseconds until next run, or -1 if no upcoming run
15
+ */
16
+ export declare function timeout(cronExpression: string | Date): number;
17
+ export declare const schedule: Scheduler;
18
+ export type Scheduler = typeof Schedule;
19
+ /**
20
+ * Schedule class for creating and managing scheduled tasks.
21
+ *
22
+ * Uses standard 5-field cron patterns (minute hour day month weekday)
23
+ * powered by `@stacksjs/cron` — auto-upgrades to native `Bun.cron.parse()`
24
+ * when available.
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * import { schedule } from '@stacksjs/scheduler'
29
+ *
30
+ * schedule.job('Inspire').hourly().setTimeZone('America/Los_Angeles')
31
+ * schedule.action('CleanupTempFiles').everyFiveMinutes()
32
+ * schedule.command('echo "maintenance"').daily()
33
+ * ```
34
+ */
35
+ export declare class Schedule implements UntimedSchedule {
36
+ constructor(task: () => void);
37
+ get pattern(): string;
38
+ everySecond(): TimedSchedule;
39
+ everyMinute(): TimedSchedule;
40
+ everyTwoMinutes(): TimedSchedule;
41
+ everyFiveMinutes(): TimedSchedule;
42
+ everyTenMinutes(): TimedSchedule;
43
+ everyThirtyMinutes(): TimedSchedule;
44
+ everyHour(): TimedSchedule;
45
+ everyDay(): TimedSchedule;
46
+ hourly(): TimedSchedule;
47
+ daily(): TimedSchedule;
48
+ weekly(): TimedSchedule;
49
+ monthly(): TimedSchedule;
50
+ yearly(): TimedSchedule;
51
+ annually(): TimedSchedule;
52
+ onDays(days: number[]): TimedSchedule;
53
+ at(time: string): TimedSchedule;
54
+ setTimeZone(timezone: Timezone): this;
55
+ withErrorHandler(handler: CatchCallbackFn): this;
56
+ withMaxRuns(runs: number): this;
57
+ withProtection(callback?: (job: ScheduledJob) => void): this;
58
+ withName(name: string): this;
59
+ withContext(context: any): this;
60
+ withInterval(seconds: number): this;
61
+ between(startAt: string | Date, stopAt: string | Date): this;
62
+ withoutOverlapping(expiresAfterMinutes?: number): this;
63
+ onOneServer(): this;
64
+ runInBackground(): this;
65
+ static job(name: string): UntimedSchedule;
66
+ static action(name: string): UntimedSchedule;
67
+ static command(cmd: string): UntimedSchedule;
68
+ static gracefulShutdown(): Promise<void>;
69
+ }
70
+ export declare class Queue extends Schedule {
71
+
72
+ }
73
+ export default Schedule;
@@ -1,7 +1,46 @@
1
- import type { CatchCallbackFn, Cron } from '@stacksjs/cron';
2
-
3
- export declare type Timezone =
4
- | 'Africa/Abidjan'
1
+ import type { CatchCallbackFn } from '@stacksjs/cron';
2
+ export declare interface ScheduledJob {
3
+ stop: () => void
4
+ nextRun: () => Date | null
5
+ }
6
+ // Base interface for common methods
7
+ export declare interface BaseSchedule {
8
+ withErrorHandler: (handler: CatchCallbackFn) => this
9
+ withMaxRuns: (runs: number) => this
10
+ withProtection: (callback?: (job: ScheduledJob) => void) => this
11
+ withName: (name: string) => this
12
+ withContext: (context: any) => this
13
+ withInterval: (seconds: number) => this
14
+ between: (startAt: string | Date, stopAt: string | Date) => this
15
+ setTimeZone: (timezone: Timezone) => this
16
+ withoutOverlapping: (expiresAfterMinutes?: number) => this
17
+ onOneServer: () => this
18
+ runInBackground: () => this
19
+ }
20
+ // Interface for schedule after timing is set
21
+ export declare interface TimedSchedule extends BaseSchedule {
22
+ }
23
+ // Interface for schedule before timing is set
24
+ export declare interface UntimedSchedule extends BaseSchedule {
25
+ everySecond: () => TimedSchedule
26
+ everyMinute: () => TimedSchedule
27
+ everyTwoMinutes: () => TimedSchedule
28
+ everyFiveMinutes: () => TimedSchedule
29
+ everyTenMinutes: () => TimedSchedule
30
+ everyThirtyMinutes: () => TimedSchedule
31
+ everyHour: () => TimedSchedule
32
+ everyDay: () => TimedSchedule
33
+ hourly: () => TimedSchedule
34
+ daily: () => TimedSchedule
35
+ weekly: () => TimedSchedule
36
+ monthly: () => TimedSchedule
37
+ yearly: () => TimedSchedule
38
+ annually: () => TimedSchedule
39
+ onDays: (days: number[]) => TimedSchedule
40
+ at: (time: string) => TimedSchedule
41
+ }
42
+ // IANA Timezone
43
+ export type Timezone = | 'Africa/Abidjan'
5
44
  | 'Africa/Accra'
6
45
  | 'Africa/Addis_Ababa'
7
46
  | 'Africa/Algiers'
@@ -65,37 +104,4 @@ export declare type Timezone =
65
104
  | 'Pacific/Auckland'
66
105
  | 'Pacific/Fiji'
67
106
  | '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
- }
107
+ | 'UTC';
package/package.json CHANGED
@@ -1,10 +1,12 @@
1
1
  {
2
2
  "name": "@stacksjs/scheduler",
3
3
  "type": "module",
4
- "version": "0.70.22",
4
+ "version": "0.70.25",
5
5
  "description": "The Stacks scheduler.",
6
6
  "author": "Chris Breuer",
7
- "contributors": ["Chris Breuer <chris@stacksjs.org>"],
7
+ "contributors": [
8
+ "Chris Breuer <chris@stacksjs.com>"
9
+ ],
8
10
  "license": "MIT",
9
11
  "funding": "https://github.com/sponsors/chrisbbreuer",
10
12
  "homepage": "https://github.com/stacksjs/stacks/tree/main/storage/framework/core/scheduler#readme",
@@ -16,26 +18,38 @@
16
18
  "bugs": {
17
19
  "url": "https://github.com/stacksjs/stacks/issues"
18
20
  },
19
- "keywords": ["scheduler", "node-cron", "jobs", "bun", "stacks"],
21
+ "keywords": [
22
+ "scheduler",
23
+ "node-cron",
24
+ "jobs",
25
+ "bun",
26
+ "stacks"
27
+ ],
20
28
  "exports": {
21
29
  ".": {
30
+ "bun": "./src/index.ts",
31
+ "types": "./dist/index.d.ts",
22
32
  "import": "./dist/index.js"
23
33
  },
24
34
  "./*": {
35
+ "bun": "./src/*",
25
36
  "import": "./dist/*"
26
37
  }
27
38
  },
28
39
  "module": "dist/index.js",
29
40
  "types": "dist/index.d.ts",
30
- "files": ["README.md", "dist"],
41
+ "files": [
42
+ "README.md",
43
+ "dist"
44
+ ],
31
45
  "scripts": {
32
46
  "build": "bun build.ts",
33
47
  "typecheck": "bun tsc --noEmit",
34
48
  "prepublishOnly": "bun run build"
35
49
  },
36
50
  "devDependencies": {
37
- "@stacksjs/actions": "0.70.18",
38
- "@stacksjs/cron": "0.70.18",
39
- "@stacksjs/development": "0.70.18"
51
+ "@stacksjs/actions": "0.70.23",
52
+ "@stacksjs/cron": "0.70.23",
53
+ "better-dx": "^0.2.12"
40
54
  }
41
55
  }
package/dist/index.d.ts DELETED
@@ -1,3 +0,0 @@
1
- export * from './run'
2
- export * from './schedule'
3
- export * from './types'
package/dist/run.d.ts DELETED
@@ -1,7 +0,0 @@
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,239 +0,0 @@
1
- import type { CatchCallbackFn, CronOptions } from '@stacksjs/cron';
2
- import type { TimedSchedule, Timezone, UntimedSchedule } from './types';
3
-
4
- export declare class Schedule implements UntimedSchedule {
5
- private static jobs = new Map<string, Cron>()
6
- private cronPattern = ''
7
- private timezone: Timezone = 'America/Los_Angeles'
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
- } = {}
20
-
21
- constructor(task: () => void) {
22
- this.task = task
23
- setTimeout(() => this.start(), 0)
24
- }
25
-
26
- everySecond(): TimedSchedule {
27
- this.cronPattern = '* * * * * *'
28
- return this as TimedSchedule
29
- }
30
-
31
- everyMinute(): TimedSchedule {
32
- this.cronPattern = '0 * * * * *'
33
- return this as TimedSchedule
34
- }
35
-
36
- everyTwoMinutes(): TimedSchedule {
37
- this.cronPattern = '*/2 * * * * *'
38
- return this as TimedSchedule
39
- }
40
-
41
- everyFiveMinutes(): TimedSchedule {
42
- this.cronPattern = '*/5 * * * *'
43
- return this as TimedSchedule
44
- }
45
-
46
- everyTenMinutes(): TimedSchedule {
47
- this.cronPattern = '*/10 * * * *'
48
- return this as TimedSchedule
49
- }
50
-
51
- everyThirtyMinutes(): TimedSchedule {
52
- this.cronPattern = '*/30 * * * *'
53
- return this as TimedSchedule
54
- }
55
-
56
- everyHour(): TimedSchedule {
57
- this.cronPattern = '0 0 * * * *'
58
- return this as TimedSchedule
59
- }
60
-
61
- everyDay(): TimedSchedule {
62
- this.cronPattern = '0 0 0 * * *'
63
- return this as TimedSchedule
64
- }
65
-
66
- hourly(): TimedSchedule {
67
- this.cronPattern = '0 0 * * * *'
68
- return this as TimedSchedule
69
- }
70
-
71
- daily(): TimedSchedule {
72
- this.cronPattern = '0 0 0 * * *'
73
- return this as TimedSchedule
74
- }
75
-
76
- weekly(): TimedSchedule {
77
- this.cronPattern = '0 0 0 * * 0'
78
- return this as TimedSchedule
79
- }
80
-
81
- monthly(): TimedSchedule {
82
- this.cronPattern = '0 0 0 1 * *'
83
- return this as TimedSchedule
84
- }
85
-
86
- yearly(): TimedSchedule {
87
- this.cronPattern = '0 0 0 1 1 *'
88
- return this as TimedSchedule
89
- }
90
-
91
- annually(): TimedSchedule {
92
- this.cronPattern = '0 0 0 1 1 *'
93
- return this as TimedSchedule
94
- }
95
-
96
- onDays(days: number[]): TimedSchedule {
97
- const dayPattern = days.join(',')
98
- this.cronPattern = `0 0 0 * * ${dayPattern}`
99
- return this as TimedSchedule
100
- }
101
-
102
- at(time: string): TimedSchedule {
103
- const [hour, minute] = time.split(':').map(Number)
104
- this.cronPattern = `${minute} ${hour} * * *`
105
- return this as TimedSchedule
106
- }
107
-
108
- setTimeZone(timezone: Timezone): this {
109
- this.timezone = timezone
110
- this.options.timezone = timezone
111
- return this
112
- }
113
-
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
137
- }
138
-
139
- withInterval(seconds: number): this {
140
- this.options.interval = seconds
141
- return this
142
- }
143
-
144
- between(startAt: string | Date, stopAt: string | Date): this {
145
- this.options.startAt = startAt
146
- this.options.stopAt = stopAt
147
- return this
148
- }
149
-
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 {
169
- return new Schedule(async () => {
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
- }
180
-
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
- }
193
-
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
- }
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()
229
-
230
- log.info('All jobs have been stopped')
231
- }
232
- }
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;
236
- export declare type Scheduler = typeof Schedule
237
- export const schedule: Scheduler = Schedule
238
-
239
- export default Schedule