@arikajs/scheduler 0.0.5

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/CHANGELOG.md ADDED
@@ -0,0 +1,21 @@
1
+ # @arikajs/scheduler
2
+
3
+ ## 0.0.5
4
+
5
+ ### Patch Changes
6
+
7
+ - feat: implement CSRF protection and standardized middleware architecture
8
+
9
+ - Added session-based CSRF protection middleware.
10
+ - Refactored middleware into project-level stubs for better customization.
11
+ - Standardized auth controller stubs.
12
+ - Enhanced CLI project scaffolding.
13
+ - Added session and localization packages.
14
+
15
+ - Updated dependencies
16
+ - @arikajs/cache@0.0.5
17
+ - @arikajs/console@0.0.5
18
+ - @arikajs/events@0.0.5
19
+ - @arikajs/foundation@0.0.5
20
+ - @arikajs/logging@0.0.5
21
+ - @arikajs/queue@0.0.5
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ArikaJs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,167 @@
1
+
2
+ ## Arika Scheduler
3
+
4
+ `@arikajs/scheduler` provides a clean, expressive, and framework-integrated task scheduling system for the ArikaJS ecosystem.
5
+
6
+ It allows you to define scheduled jobs directly in code using a fluent API โ€” designed for elegance and clarity โ€” while remaining lightweight and Node.js-native.
7
+
8
+ The scheduler is designed to work seamlessly with `@arikajs/foundation`, `@arikajs/queue`, and `@arikajs/logging`.
9
+
10
+ ---
11
+
12
+ ## โœจ Features
13
+
14
+ - **๐Ÿ•’ Fluent scheduling API**: Expressive and readable schedule definitions
15
+ - **โšก Parallel Execution**: Non-blocking task execution for high performance
16
+ - **๐Ÿ† Cluster Safety**: Leader election prevents double-execution in distributed environments
17
+ - **๐Ÿ” Cron-based scheduling**: Full support for standard cron expressions
18
+ - **โฑ Human-readable intervals**: Preset methods like `everyMinute()`, `hourly()`, `daily()`
19
+ - **๐Ÿงต Queue integration**: Dispatch jobs directly to the background instead of blocking
20
+ - **๐Ÿชต Logging integration**: Automatically logs task starts, completions, and failures
21
+ - **๐Ÿ›ก๏ธ Task Control**: Built-in support for timeouts and automatic retries
22
+ - **๐Ÿ“ก Lifecycle Events**: Real-time monitoring via `@arikajs/events`
23
+ - **๐ŸŒ Timezone support**: Run tasks relative to your preferred global or local timezone
24
+ - **๐Ÿ›‘ Graceful Shutdown**: Safe worker termination without dropping tasks
25
+ - **๐ŸŸฆ TypeScript-first**: Full type safety for all scheduling operations
26
+
27
+ ---
28
+
29
+ ## ๐Ÿ“ฆ Installation
30
+
31
+ ```bash
32
+ npm install @arikajs/scheduler
33
+ ```
34
+
35
+ **Requires:**
36
+ - `@arikajs/foundation`
37
+ - `@arikajs/logging`
38
+ - `@arikajs/cache` (recommended for overlapping & cluster locks)
39
+ - `@arikajs/events` (optional, for monitoring)
40
+
41
+ ---
42
+
43
+ ## ๐Ÿš€ Quick Start
44
+
45
+ ### 1๏ธโƒฃ Define Scheduled Tasks
46
+
47
+ Create a scheduler definition file (e.g., `app/Console/Kernel.ts`):
48
+
49
+ ```ts
50
+ import { Schedule } from '@arikajs/scheduler';
51
+
52
+ export default (schedule: Schedule) => {
53
+ // Run a closure every minute with a name
54
+ schedule.call(() => {
55
+ console.log('Running every minute');
56
+ }).everyMinute().name('important-sync');
57
+
58
+ // Run a CLI command daily with timeout and retries
59
+ schedule.command('app:cleanup')
60
+ .daily()
61
+ .timeout(60) // 1 minute timeout
62
+ .retry(3, 10); // retry 3 times with 10s delay
63
+
64
+ // Dispatch a job to the queue hourly
65
+ schedule.job(CleanupJob).hourly();
66
+ };
67
+ ```
68
+
69
+ ### 2๏ธโƒฃ Run the Scheduler
70
+
71
+ You can run the scheduler in two modes:
72
+
73
+ **Long-running Daemon (Recommended for Production)**
74
+ ```bash
75
+ arika schedule:work
76
+ ```
77
+
78
+ **Single Run (For Cron Jobs)**
79
+ ```bash
80
+ * * * * * cd /path-to-your-project && node artisan schedule:run >> /dev/null 2>&1
81
+ ```
82
+
83
+ ---
84
+
85
+ ## ๐Ÿ“… Defining Tasks
86
+
87
+ ### ๐Ÿ” Run a Closure
88
+ ```ts
89
+ schedule.call(async () => {
90
+ await db.table('users').where('active', false).delete();
91
+ }).everyMinute();
92
+ ```
93
+
94
+ ### ๐Ÿงพ Run a Command
95
+ ```ts
96
+ schedule.command('cache:clear').dailyAt('02:00');
97
+ ```
98
+
99
+ ---
100
+
101
+ ## ๐Ÿ›ก Advanced Usage
102
+
103
+ ### Parallel Execution & Leader Election
104
+ The scheduler automatically runs all due tasks in parallel so complex tasks don't block simple ones.
105
+
106
+ In a clustered environment (multiple servers/containers), the scheduler uses `@arikajs/cache` to perform **Leader Election**. Only one server will process the schedule for any given minute, ensuring safety without extra configuration.
107
+
108
+ ### Preventing Overlaps
109
+ If a specific task should not start if its previous instance is still active:
110
+ ```ts
111
+ schedule
112
+ .command('report:generate')
113
+ .everyMinute()
114
+ .withoutOverlapping();
115
+ ```
116
+
117
+ ### Timezone & Retries
118
+ ```ts
119
+ schedule
120
+ .command('backup:run')
121
+ .dailyAt('01:00')
122
+ .timezone('Asia/Kolkata')
123
+ .retry(3, 30); // Retry 3 times with 30s delay between attempts
124
+ ```
125
+
126
+ ### Monitoring via Events
127
+ The scheduler emits events that you can listen to in your `EventsServiceProvider`:
128
+ - `scheduler.TaskStarting`
129
+ - `scheduler.TaskFinished
130
+ - `scheduler.TaskFailed`
131
+
132
+ ```ts
133
+ Event.listen('scheduler.TaskFailed', (data) => {
134
+ Log.error(`CRITICAL: Task ${data.task} failed! Error: ${data.err.message}`);
135
+ });
136
+ ```
137
+
138
+ ---
139
+
140
+ ## ๐Ÿ— Architecture
141
+
142
+ ```text
143
+ scheduler/
144
+ โ”œโ”€โ”€ src/
145
+ โ”‚ โ”œโ”€โ”€ Contracts
146
+ โ”‚ โ”‚ โ””โ”€โ”€ Task.ts
147
+ โ”‚ โ”œโ”€โ”€ Mutex
148
+ โ”‚ โ”œโ”€โ”€ Event.ts
149
+ โ”‚ โ”œโ”€โ”€ index.ts
150
+ โ”‚ โ”œโ”€โ”€ Schedule.ts
151
+ โ”‚ โ”œโ”€โ”€ Scheduler.ts
152
+ โ”‚ โ””โ”€โ”€ Worker.ts
153
+ โ”œโ”€โ”€ tests/
154
+ โ”œโ”€โ”€ package.json
155
+ โ”œโ”€โ”€ tsconfig.json
156
+ โ””โ”€โ”€ README.md
157
+ ```
158
+
159
+ ## ๐Ÿ“„ License
160
+
161
+ `@arikajs/scheduler` is open-source software licensed under the **MIT License**.
162
+
163
+ ---
164
+
165
+ ## ๐Ÿงญ Philosophy
166
+
167
+ > "If it must run, it must run reliably."
@@ -0,0 +1,14 @@
1
+ export interface Task {
2
+ /**
3
+ * Run the scheduled task.
4
+ */
5
+ run(): Promise<void> | void;
6
+ /**
7
+ * Get the cron expression for the task.
8
+ */
9
+ expression(): string;
10
+ /**
11
+ * Determine if the task is due to run.
12
+ */
13
+ isDue(date: Date, timezone?: string): boolean;
14
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=Task.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Task.js","sourceRoot":"","sources":["../../src/Contracts/Task.ts"],"names":[],"mappings":""}
@@ -0,0 +1,44 @@
1
+ import { Task } from './Contracts/Task';
2
+ export declare class Event implements Task {
3
+ readonly command: string | Function;
4
+ protected cronExpression: string;
5
+ protected timezoneVal?: string;
6
+ protected withoutOverlappingVal: boolean;
7
+ protected expiresAt: number;
8
+ protected successCallbacks: Function[];
9
+ protected failureCallbacks: (Function)[];
10
+ protected timeoutVal: number;
11
+ protected retriesVal: number;
12
+ protected retryDelayVal: number;
13
+ protected descriptionVal: string;
14
+ constructor(command: string | Function);
15
+ name(description: string): this;
16
+ timeout(seconds: number): this;
17
+ retry(times: number, delay?: number): this;
18
+ cron(expression: string): this;
19
+ timezone(timezone: string): this;
20
+ withoutOverlapping(expiresAt?: number): this;
21
+ onSuccess(callback: Function): this;
22
+ onFailure(callback: Function): this;
23
+ everySecond(): this;
24
+ everyMinute(): this;
25
+ everyFiveMinutes(): this;
26
+ everyTenMinutes(): this;
27
+ hourly(): this;
28
+ hourlyAt(minute: number): this;
29
+ daily(): this;
30
+ dailyAt(time: string): this;
31
+ weekly(): this;
32
+ weeklyOn(day: number, time?: string): this;
33
+ monthly(): this;
34
+ monthlyOn(day: number, time?: string): this;
35
+ expression(): string;
36
+ isDue(date: Date, timezone?: string): boolean;
37
+ run(): Promise<void>;
38
+ shouldSkipOverlapping(): boolean;
39
+ mutexExpiration(): number;
40
+ getTimeout(): number;
41
+ getRetries(): number;
42
+ getRetryDelay(): number;
43
+ getDescription(): string;
44
+ }
package/dist/Event.js ADDED
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Event = void 0;
7
+ const cron_parser_1 = __importDefault(require("cron-parser"));
8
+ class Event {
9
+ command;
10
+ cronExpression = '* * * * *';
11
+ timezoneVal;
12
+ withoutOverlappingVal = false;
13
+ expiresAt = 1440; // 24 hours default for overlap lock
14
+ successCallbacks = [];
15
+ failureCallbacks = [];
16
+ timeoutVal = 0;
17
+ retriesVal = 0;
18
+ retryDelayVal = 0;
19
+ descriptionVal = '';
20
+ constructor(command) {
21
+ this.command = command;
22
+ }
23
+ name(description) {
24
+ this.descriptionVal = description;
25
+ return this;
26
+ }
27
+ timeout(seconds) {
28
+ this.timeoutVal = seconds;
29
+ return this;
30
+ }
31
+ retry(times, delay = 0) {
32
+ this.retriesVal = times;
33
+ this.retryDelayVal = delay;
34
+ return this;
35
+ }
36
+ cron(expression) {
37
+ this.cronExpression = expression;
38
+ return this;
39
+ }
40
+ timezone(timezone) {
41
+ this.timezoneVal = timezone;
42
+ return this;
43
+ }
44
+ withoutOverlapping(expiresAt = 1440) {
45
+ this.withoutOverlappingVal = true;
46
+ this.expiresAt = expiresAt;
47
+ return this;
48
+ }
49
+ onSuccess(callback) {
50
+ this.successCallbacks.push(callback);
51
+ return this;
52
+ }
53
+ onFailure(callback) {
54
+ this.failureCallbacks.push(callback);
55
+ return this;
56
+ }
57
+ // Frequencies
58
+ everySecond() { return this.cron('* * * * * *'); }
59
+ everyMinute() { return this.cron('* * * * *'); }
60
+ everyFiveMinutes() { return this.cron('*/5 * * * *'); }
61
+ everyTenMinutes() { return this.cron('*/10 * * * *'); }
62
+ hourly() { return this.cron('0 * * * *'); }
63
+ hourlyAt(minute) { return this.cron(`${minute} * * * *`); }
64
+ daily() { return this.cron('0 0 * * *'); }
65
+ dailyAt(time) {
66
+ const [hour, minute] = time.split(':');
67
+ return this.cron(`${minute} ${hour} * * *`);
68
+ }
69
+ weekly() { return this.cron('0 0 * * 0'); }
70
+ weeklyOn(day, time = '00:00') {
71
+ const [hour, minute] = time.split(':');
72
+ return this.cron(`${minute} ${hour} * * ${day}`);
73
+ }
74
+ monthly() { return this.cron('0 0 1 * *'); }
75
+ monthlyOn(day, time = '00:00') {
76
+ const [hour, minute] = time.split(':');
77
+ return this.cron(`${minute} ${hour} ${day} * *`);
78
+ }
79
+ expression() {
80
+ return this.cronExpression;
81
+ }
82
+ isDue(date, timezone) {
83
+ const options = {
84
+ currentDate: new Date(date.getTime() - 1000),
85
+ tz: this.timezoneVal || timezone
86
+ };
87
+ try {
88
+ const interval = cron_parser_1.default.parseExpression(this.cronExpression, options);
89
+ const next = interval.next().toDate();
90
+ return next.getMinutes() === date.getMinutes() &&
91
+ next.getHours() === date.getHours() &&
92
+ next.getDate() === date.getDate() &&
93
+ next.getMonth() === date.getMonth() &&
94
+ next.getFullYear() === date.getFullYear();
95
+ }
96
+ catch (e) {
97
+ return false;
98
+ }
99
+ }
100
+ async run() {
101
+ try {
102
+ if (typeof this.command === 'function') {
103
+ await this.command();
104
+ }
105
+ else {
106
+ // For commands, we would usually use the CommandRegistry
107
+ // But this will be handled by the Scheduler runner
108
+ }
109
+ for (const callback of this.successCallbacks) {
110
+ await callback();
111
+ }
112
+ }
113
+ catch (e) {
114
+ for (const callback of this.failureCallbacks) {
115
+ await callback(e);
116
+ }
117
+ throw e;
118
+ }
119
+ }
120
+ shouldSkipOverlapping() {
121
+ return this.withoutOverlappingVal;
122
+ }
123
+ mutexExpiration() {
124
+ return this.expiresAt;
125
+ }
126
+ getTimeout() {
127
+ return this.timeoutVal;
128
+ }
129
+ getRetries() {
130
+ return this.retriesVal;
131
+ }
132
+ getRetryDelay() {
133
+ return this.retryDelayVal;
134
+ }
135
+ getDescription() {
136
+ return this.descriptionVal;
137
+ }
138
+ }
139
+ exports.Event = Event;
140
+ //# sourceMappingURL=Event.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Event.js","sourceRoot":"","sources":["../src/Event.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { Event } from './Event';
2
+ export declare class Schedule {
3
+ protected events: Event[];
4
+ /**
5
+ * Add a new callback event to the schedule.
6
+ */
7
+ call(callback: Function): Event;
8
+ /**
9
+ * Add a new command event to the schedule.
10
+ */
11
+ command(command: string): Event;
12
+ /**
13
+ * Add a new job event to the schedule.
14
+ */
15
+ job(job: any): Event;
16
+ /**
17
+ * Get all events.
18
+ */
19
+ allEvents(): Event[];
20
+ /**
21
+ * Get due events.
22
+ */
23
+ dueEvents(date: Date, timezone?: string): Event[];
24
+ }
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Schedule = void 0;
4
+ const Event_1 = require("./Event");
5
+ class Schedule {
6
+ events = [];
7
+ /**
8
+ * Add a new callback event to the schedule.
9
+ */
10
+ call(callback) {
11
+ const event = new Event_1.Event(callback);
12
+ this.events.push(event);
13
+ return event;
14
+ }
15
+ /**
16
+ * Add a new command event to the schedule.
17
+ */
18
+ command(command) {
19
+ const event = new Event_1.Event(command);
20
+ this.events.push(event);
21
+ return event;
22
+ }
23
+ /**
24
+ * Add a new job event to the schedule.
25
+ */
26
+ job(job) {
27
+ const event = new Event_1.Event(async () => {
28
+ const { Queue } = await import('@arikajs/queue');
29
+ await Queue.dispatch(job);
30
+ });
31
+ this.events.push(event);
32
+ return event;
33
+ }
34
+ /**
35
+ * Get all events.
36
+ */
37
+ allEvents() {
38
+ return this.events;
39
+ }
40
+ /**
41
+ * Get due events.
42
+ */
43
+ dueEvents(date, timezone) {
44
+ return this.events.filter(event => event.isDue(date, timezone));
45
+ }
46
+ }
47
+ exports.Schedule = Schedule;
48
+ //# sourceMappingURL=Schedule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Schedule.js","sourceRoot":"","sources":["../src/Schedule.ts"],"names":[],"mappings":";;;AACA,mCAAgC;AAEhC,MAAa,QAAQ;IACP,MAAM,GAAY,EAAE,CAAC;IAE/B;;OAEG;IACI,IAAI,CAAC,QAAkB;QAC1B,MAAM,KAAK,GAAG,IAAI,aAAK,CAAC,QAAQ,CAAC,CAAC;QAClC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,OAAO,KAAK,CAAC;IACjB,CAAC;IAED;;OAEG;IACI,OAAO,CAAC,OAAe;QAC1B,MAAM,KAAK,GAAG,IAAI,aAAK,CAAC,OAAO,CAAC,CAAC;QACjC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,OAAO,KAAK,CAAC;IACjB,CAAC;IAED;;OAEG;IACI,GAAG,CAAC,GAAQ;QACf,MAAM,KAAK,GAAG,IAAI,aAAK,CAAC,KAAK,IAAI,EAAE;YAC/B,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;YACjD,MAAM,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,OAAO,KAAK,CAAC;IACjB,CAAC;IAED;;OAEG;IACI,SAAS;QACZ,OAAO,IAAI,CAAC,MAAM,CAAC;IACvB,CAAC;IAED;;OAEG;IACI,SAAS,CAAC,IAAU,EAAE,QAAiB;QAC1C,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;IACpE,CAAC;CACJ;AA9CD,4BA8CC"}
@@ -0,0 +1,27 @@
1
+ import { Container } from '@arikajs/foundation';
2
+ import { Schedule } from './Schedule';
3
+ import { Event } from './Event';
4
+ export declare class Scheduler {
5
+ protected container: Container;
6
+ protected schedule: Schedule;
7
+ constructor(container: Container);
8
+ /**
9
+ * Define the schedule.
10
+ */
11
+ define(callback: (schedule: Schedule) => void): this;
12
+ /**
13
+ * Run the scheduled tasks.
14
+ */
15
+ run(date?: Date): Promise<void>;
16
+ protected shouldSkipBecauseAnotherInstanceIsRunning(): Promise<boolean>;
17
+ protected runEvent(event: Event): Promise<void>;
18
+ protected executeWithRetries(event: Event): Promise<void>;
19
+ protected executeWithTimeout(event: Event): Promise<void>;
20
+ protected actuallyRun(event: Event): Promise<void>;
21
+ protected dispatchLifecycleEvent(type: string, event: Event, extra?: any): Promise<void>;
22
+ protected getEventName(event: Event): string;
23
+ protected isLocked(event: Event): Promise<boolean>;
24
+ protected lock(event: Event): Promise<void>;
25
+ protected unlock(event: Event): Promise<void>;
26
+ protected getMutexName(event: Event): string;
27
+ }