@commandkit/tasks 0.0.0-dev.20250725125550 → 0.0.0-dev.20250726103524
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/README.md +77 -199
- package/dist/driver-manager.d.ts +3 -4
- package/dist/driver-manager.js +4 -5
- package/dist/drivers/bullmq.js +7 -7
- package/dist/drivers/sqlite.d.ts +63 -0
- package/dist/drivers/sqlite.js +179 -0
- package/dist/task.d.ts +5 -0
- package/dist/task.js +12 -3
- package/dist/types.d.ts +6 -16
- package/package.json +7 -8
- package/dist/drivers/hypercron.d.ts +0 -69
- package/dist/drivers/hypercron.js +0 -90
package/README.md
CHANGED
|
@@ -25,15 +25,21 @@ import { tasks } from '@commandkit/tasks';
|
|
|
25
25
|
|
|
26
26
|
export default {
|
|
27
27
|
plugins: [
|
|
28
|
-
tasks(
|
|
29
|
-
tasksPath: 'app/tasks', // optional, defaults to 'app/tasks'
|
|
30
|
-
enableHMR: true, // optional, defaults to true in development
|
|
31
|
-
}),
|
|
28
|
+
tasks(),
|
|
32
29
|
],
|
|
33
30
|
};
|
|
34
31
|
```
|
|
35
32
|
|
|
36
|
-
### 2.
|
|
33
|
+
### 2. Set up a driver
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import { setDriver } from '@commandkit/tasks';
|
|
37
|
+
import { SQLiteDriver } from '@commandkit/tasks/sqlite';
|
|
38
|
+
|
|
39
|
+
setDriver(new SQLiteDriver('./tasks.db'));
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### 3. Create static tasks
|
|
37
43
|
|
|
38
44
|
Create a file in `src/app/tasks/`:
|
|
39
45
|
|
|
@@ -42,95 +48,86 @@ import { task } from '@commandkit/tasks';
|
|
|
42
48
|
|
|
43
49
|
export const refreshExchangeRate = task({
|
|
44
50
|
name: 'refresh-exchange-rate',
|
|
45
|
-
schedule: '0 0 * * *', //
|
|
51
|
+
schedule: { type: 'cron', value: '0 0 * * *' }, // daily at midnight
|
|
46
52
|
async execute(ctx) {
|
|
47
53
|
// Fetch latest exchange rates
|
|
48
54
|
const rates = await fetchExchangeRates();
|
|
49
55
|
await updateDatabase(rates);
|
|
50
56
|
},
|
|
51
57
|
});
|
|
52
|
-
|
|
53
|
-
export const cleanupOldData = task({
|
|
54
|
-
name: 'cleanup-old-data',
|
|
55
|
-
schedule: () => new Date(Date.now() + 24 * 60 * 60 * 1000), // tomorrow
|
|
56
|
-
async prepare(ctx) {
|
|
57
|
-
// Only run if there's old data to clean
|
|
58
|
-
return await hasOldData();
|
|
59
|
-
},
|
|
60
|
-
async execute(ctx) {
|
|
61
|
-
await cleanupOldRecords();
|
|
62
|
-
},
|
|
63
|
-
});
|
|
64
58
|
```
|
|
65
59
|
|
|
66
|
-
###
|
|
60
|
+
### 4. Create dynamic tasks from commands
|
|
67
61
|
|
|
68
62
|
```ts
|
|
63
|
+
import type { CommandData, ChatInputCommand } from 'commandkit';
|
|
64
|
+
import { ApplicationCommandOptionType } from 'discord.js';
|
|
65
|
+
import ms from 'ms';
|
|
69
66
|
import { createTask } from '@commandkit/tasks';
|
|
70
67
|
|
|
71
|
-
export
|
|
68
|
+
export const command: CommandData = {
|
|
72
69
|
name: 'remind-me',
|
|
73
70
|
description: 'Set a reminder',
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
71
|
+
options: [
|
|
72
|
+
{
|
|
73
|
+
name: 'time',
|
|
74
|
+
description: 'The time to remind after. Eg: 6h, 10m, 1d',
|
|
75
|
+
type: ApplicationCommandOptionType.String,
|
|
76
|
+
required: true,
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
name: 'message',
|
|
80
|
+
description: 'The message to remind about.',
|
|
81
|
+
type: ApplicationCommandOptionType.String,
|
|
82
|
+
required: true,
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export const chatInput: ChatInputCommand = async (ctx) => {
|
|
88
|
+
const time = ctx.options.getString('time', true);
|
|
89
|
+
const message = ctx.options.getString('message', true);
|
|
90
|
+
const timeMs = Date.now() + ms(time as `${number}`);
|
|
91
|
+
|
|
92
|
+
await createTask({
|
|
93
|
+
name: 'reminder',
|
|
94
|
+
data: {
|
|
95
|
+
userId: ctx.interaction.user.id,
|
|
96
|
+
message,
|
|
97
|
+
channelId: ctx.interaction.channelId,
|
|
98
|
+
setAt: Date.now(),
|
|
99
|
+
},
|
|
100
|
+
schedule: {
|
|
101
|
+
type: 'date',
|
|
102
|
+
value: timeMs,
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
await ctx.interaction.reply(
|
|
107
|
+
`I will remind you <t:${Math.floor(timeMs / 1000)}:R> for \`${message}\``,
|
|
108
|
+
);
|
|
89
109
|
};
|
|
90
110
|
```
|
|
91
111
|
|
|
92
112
|
## API Reference
|
|
93
113
|
|
|
94
|
-
### Plugin Options
|
|
95
|
-
|
|
96
|
-
```ts
|
|
97
|
-
interface TasksPluginOptions {
|
|
98
|
-
tasksPath?: string; // Path to tasks directory, defaults to 'app/tasks'
|
|
99
|
-
enableHMR?: boolean; // Enable HMR for tasks, defaults to true in development
|
|
100
|
-
}
|
|
101
|
-
```
|
|
102
|
-
|
|
103
114
|
### Task Definition
|
|
104
115
|
|
|
105
116
|
```ts
|
|
106
117
|
interface TaskDefinition {
|
|
107
118
|
name: string;
|
|
108
|
-
schedule?:
|
|
109
|
-
prepare?: (ctx: TaskContext) => Promise<boolean
|
|
110
|
-
execute: (ctx: TaskContext) => Promise<void
|
|
119
|
+
schedule?: TaskSchedule;
|
|
120
|
+
prepare?: (ctx: TaskContext) => Promise<boolean>;
|
|
121
|
+
execute: (ctx: TaskContext) => Promise<void>;
|
|
111
122
|
}
|
|
112
123
|
```
|
|
113
124
|
|
|
114
125
|
### Schedule Types
|
|
115
126
|
|
|
116
127
|
```ts
|
|
117
|
-
type
|
|
118
|
-
|
|
|
119
|
-
| number
|
|
120
|
-
| string // cron expression or date string
|
|
121
|
-
| (() => Date | number | string); // dynamic schedule
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
**Cron Expressions**: The plugin supports standard cron expressions (e.g., `'0 0 * * *'` for daily at midnight). Cron parsing is handled by `cron-parser` for in-memory and SQLite drivers, while BullMQ uses its built-in cron support.
|
|
125
|
-
|
|
126
|
-
### Task Context
|
|
127
|
-
|
|
128
|
-
```ts
|
|
129
|
-
interface TaskContext {
|
|
130
|
-
task: TaskData;
|
|
131
|
-
commandkit: CommandKit;
|
|
132
|
-
client: Client;
|
|
133
|
-
}
|
|
128
|
+
type TaskSchedule =
|
|
129
|
+
| { type: 'cron'; value: string; timezone?: string }
|
|
130
|
+
| { type: 'date'; value: Date | number; timezone?: string };
|
|
134
131
|
```
|
|
135
132
|
|
|
136
133
|
### Functions
|
|
@@ -139,163 +136,44 @@ interface TaskContext {
|
|
|
139
136
|
|
|
140
137
|
Creates a task definition.
|
|
141
138
|
|
|
142
|
-
|
|
143
|
-
import { task } from '@commandkit/tasks';
|
|
144
|
-
|
|
145
|
-
export const myTask = task({
|
|
146
|
-
name: 'my-task',
|
|
147
|
-
schedule: '0 0 * * *',
|
|
148
|
-
async execute(ctx) {
|
|
149
|
-
// Task logic here
|
|
150
|
-
},
|
|
151
|
-
});
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
#### `createTask(options: CreateTaskOptions)`
|
|
139
|
+
#### `createTask(task: TaskData)`
|
|
155
140
|
|
|
156
141
|
Creates a dynamic task.
|
|
157
142
|
|
|
158
|
-
|
|
159
|
-
import { createTask } from '@commandkit/tasks';
|
|
160
|
-
|
|
161
|
-
await createTask({
|
|
162
|
-
name: 'reminder',
|
|
163
|
-
schedule: new Date(Date.now() + 60000), // 1 minute from now
|
|
164
|
-
data: { userId: '123', message: 'Hello!' },
|
|
165
|
-
});
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
#### `executeTask(taskOrName: TaskDefinition | string)`
|
|
169
|
-
|
|
170
|
-
Executes a task immediately.
|
|
171
|
-
|
|
172
|
-
```ts
|
|
173
|
-
import { executeTask } from '@commandkit/tasks';
|
|
174
|
-
|
|
175
|
-
await executeTask('my-task');
|
|
176
|
-
// or
|
|
177
|
-
await executeTask(myTask);
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
#### `cancelTask(taskOrName: TaskDefinition | string)`
|
|
181
|
-
|
|
182
|
-
Cancels a scheduled task.
|
|
183
|
-
|
|
184
|
-
```ts
|
|
185
|
-
import { cancelTask } from '@commandkit/tasks';
|
|
186
|
-
|
|
187
|
-
await cancelTask('my-task');
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
#### `pauseTask(taskOrName: TaskDefinition | string)`
|
|
191
|
-
|
|
192
|
-
Pauses a task.
|
|
193
|
-
|
|
194
|
-
```ts
|
|
195
|
-
import { pauseTask } from '@commandkit/tasks';
|
|
196
|
-
|
|
197
|
-
await pauseTask('my-task');
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
#### `resumeTask(taskOrName: TaskDefinition | string)`
|
|
201
|
-
|
|
202
|
-
Resumes a paused task.
|
|
203
|
-
|
|
204
|
-
```ts
|
|
205
|
-
import { resumeTask } from '@commandkit/tasks';
|
|
206
|
-
|
|
207
|
-
await resumeTask('my-task');
|
|
208
|
-
```
|
|
143
|
+
#### `deleteTask(identifier: string)`
|
|
209
144
|
|
|
210
|
-
|
|
145
|
+
Deletes a scheduled task.
|
|
211
146
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
### In-Memory Driver (Default)
|
|
215
|
-
|
|
216
|
-
```ts
|
|
217
|
-
import { driver } from '@commandkit/tasks';
|
|
218
|
-
import { InMemoryDriver } from '@commandkit/tasks/drivers';
|
|
219
|
-
|
|
220
|
-
driver.use(new InMemoryDriver());
|
|
221
|
-
```
|
|
147
|
+
## Drivers
|
|
222
148
|
|
|
223
149
|
### SQLite Driver
|
|
224
150
|
|
|
151
|
+
Persistent job queue with recovery on restart.
|
|
152
|
+
|
|
225
153
|
```ts
|
|
226
|
-
import {
|
|
227
|
-
import { SQLiteDriver } from '@commandkit/tasks/drivers';
|
|
154
|
+
import { SQLiteDriver } from '@commandkit/tasks/sqlite';
|
|
228
155
|
|
|
229
|
-
|
|
156
|
+
setDriver(new SQLiteDriver('./tasks.db'));
|
|
230
157
|
```
|
|
231
158
|
|
|
232
|
-
**
|
|
159
|
+
**Features:**
|
|
160
|
+
- Jobs recoverable on restart
|
|
161
|
+
- Persistent job data
|
|
162
|
+
- Cron expression support via cron-parser
|
|
233
163
|
|
|
234
164
|
### BullMQ Driver
|
|
235
165
|
|
|
166
|
+
Distributed task scheduling with Redis.
|
|
167
|
+
|
|
236
168
|
```ts
|
|
237
|
-
import {
|
|
238
|
-
import { BullMQDriver } from '@commandkit/tasks/drivers';
|
|
169
|
+
import { BullMQDriver } from '@commandkit/tasks/bullmq';
|
|
239
170
|
|
|
240
|
-
|
|
171
|
+
setDriver(new BullMQDriver({
|
|
241
172
|
host: 'localhost',
|
|
242
173
|
port: 6379,
|
|
243
174
|
}));
|
|
244
175
|
```
|
|
245
176
|
|
|
246
|
-
**Note**: Requires `bullmq` package to be installed. BullMQ has built-in cron support, so no additional cron parsing is needed.
|
|
247
|
-
|
|
248
|
-
## Examples
|
|
249
|
-
|
|
250
|
-
### Scheduled Database Backup
|
|
251
|
-
|
|
252
|
-
```ts
|
|
253
|
-
import { task } from '@commandkit/tasks';
|
|
254
|
-
|
|
255
|
-
export const databaseBackup = task({
|
|
256
|
-
name: 'database-backup',
|
|
257
|
-
schedule: '0 2 * * *', // Daily at 2 AM
|
|
258
|
-
async execute(ctx) {
|
|
259
|
-
const backup = await createBackup();
|
|
260
|
-
await uploadToCloud(backup);
|
|
261
|
-
await ctx.client.channels.cache.get('backup-log')?.send('Backup completed!');
|
|
262
|
-
},
|
|
263
|
-
});
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
### User Reminder System
|
|
267
|
-
|
|
268
|
-
```ts
|
|
269
|
-
import { task } from '@commandkit/tasks';
|
|
270
|
-
|
|
271
|
-
export const reminder = task({
|
|
272
|
-
name: 'reminder',
|
|
273
|
-
async execute(ctx) {
|
|
274
|
-
const { userId, message } = ctx.task.data;
|
|
275
|
-
const user = await ctx.client.users.fetch(userId);
|
|
276
|
-
await user.send(`Reminder: ${message}`);
|
|
277
|
-
},
|
|
278
|
-
});
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
### Conditional Task
|
|
282
|
-
|
|
283
|
-
```ts
|
|
284
|
-
import { task } from '@commandkit/tasks';
|
|
285
|
-
|
|
286
|
-
export const maintenanceCheck = task({
|
|
287
|
-
name: 'maintenance-check',
|
|
288
|
-
schedule: '0 */6 * * *', // Every 6 hours
|
|
289
|
-
async prepare(ctx) {
|
|
290
|
-
// Only run if maintenance mode is not enabled
|
|
291
|
-
return !ctx.commandkit.store.get('maintenance-mode');
|
|
292
|
-
},
|
|
293
|
-
async execute(ctx) {
|
|
294
|
-
await performMaintenanceChecks();
|
|
295
|
-
},
|
|
296
|
-
});
|
|
297
|
-
```
|
|
298
|
-
|
|
299
177
|
## License
|
|
300
178
|
|
|
301
179
|
MIT
|
package/dist/driver-manager.d.ts
CHANGED
|
@@ -10,10 +10,9 @@ import { TaskData } from './types';
|
|
|
10
10
|
* @example
|
|
11
11
|
* ```ts
|
|
12
12
|
* import { TaskDriverManager } from '@commandkit/tasks';
|
|
13
|
-
* import { HyperCronDriver } from '@commandkit/tasks/hypercron';
|
|
14
13
|
*
|
|
15
14
|
* const manager = new TaskDriverManager();
|
|
16
|
-
*
|
|
15
|
+
* // Set your preferred driver here
|
|
17
16
|
*
|
|
18
17
|
* // Now you can create and manage tasks
|
|
19
18
|
* const taskId = await manager.createTask({
|
|
@@ -83,9 +82,9 @@ export declare const taskDriverManager: TaskDriverManager;
|
|
|
83
82
|
* @example
|
|
84
83
|
* ```ts
|
|
85
84
|
* import { setDriver } from '@commandkit/tasks';
|
|
86
|
-
* import {
|
|
85
|
+
* import { SQLiteDriver } from '@commandkit/tasks/sqlite';
|
|
87
86
|
*
|
|
88
|
-
* setDriver(new
|
|
87
|
+
* setDriver(new SQLiteDriver('./tasks.db'));
|
|
89
88
|
* ```
|
|
90
89
|
*/
|
|
91
90
|
export declare function setDriver(driver: TaskDriver): void;
|
package/dist/driver-manager.js
CHANGED
|
@@ -14,10 +14,9 @@ exports.deleteTask = deleteTask;
|
|
|
14
14
|
* @example
|
|
15
15
|
* ```ts
|
|
16
16
|
* import { TaskDriverManager } from '@commandkit/tasks';
|
|
17
|
-
* import { HyperCronDriver } from '@commandkit/tasks/hypercron';
|
|
18
17
|
*
|
|
19
18
|
* const manager = new TaskDriverManager();
|
|
20
|
-
*
|
|
19
|
+
* // Set your preferred driver here
|
|
21
20
|
*
|
|
22
21
|
* // Now you can create and manage tasks
|
|
23
22
|
* const taskId = await manager.createTask({
|
|
@@ -104,9 +103,9 @@ exports.taskDriverManager = new TaskDriverManager();
|
|
|
104
103
|
* @example
|
|
105
104
|
* ```ts
|
|
106
105
|
* import { setDriver } from '@commandkit/tasks';
|
|
107
|
-
* import {
|
|
106
|
+
* import { SQLiteDriver } from '@commandkit/tasks/sqlite';
|
|
108
107
|
*
|
|
109
|
-
* setDriver(new
|
|
108
|
+
* setDriver(new SQLiteDriver('./tasks.db'));
|
|
110
109
|
* ```
|
|
111
110
|
*/
|
|
112
111
|
function setDriver(driver) {
|
|
@@ -151,4 +150,4 @@ function createTask(task) {
|
|
|
151
150
|
function deleteTask(identifier) {
|
|
152
151
|
return exports.taskDriverManager.deleteTask(identifier);
|
|
153
152
|
}
|
|
154
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
153
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJpdmVyLW1hbmFnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvZHJpdmVyLW1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBOEdBLDhCQUVDO0FBcUJELGdDQUVDO0FBZ0JELGdDQUVDO0FBdEpEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FxQkc7QUFDSCxNQUFhLGlCQUFpQjtJQUE5QjtRQUNVLFdBQU0sR0FBc0IsSUFBSSxDQUFDO0lBMkQzQyxDQUFDO0lBekRDOzs7Ozs7O09BT0c7SUFDSSxTQUFTLENBQUMsTUFBa0I7UUFDakMsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7SUFDdkIsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNJLEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBYztRQUNwQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU07WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLDhCQUE4QixDQUFDLENBQUM7UUFFbEUsT0FBTyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3hDLENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNJLEtBQUssQ0FBQyxVQUFVLENBQUMsVUFBa0I7UUFDeEMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO1FBRWxFLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0ksS0FBSyxDQUFDLGFBQWEsQ0FBQyxNQUFrQjtRQUMzQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU07WUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLDhCQUE4QixDQUFDLENBQUM7UUFFbEUsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMxQyxDQUFDO0NBQ0Y7QUE1REQsOENBNERDO0FBRUQ7Ozs7O0dBS0c7QUFDVSxRQUFBLGlCQUFpQixHQUFHLElBQUksaUJBQWlCLEVBQUUsQ0FBQztBQUV6RDs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILFNBQWdCLFNBQVMsQ0FBQyxNQUFrQjtJQUMxQyx5QkFBaUIsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDdEMsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FrQkc7QUFDSCxTQUFnQixVQUFVLENBQUMsSUFBYztJQUN2QyxPQUFPLHlCQUFpQixDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUM1QyxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUNILFNBQWdCLFVBQVUsQ0FBQyxVQUFrQjtJQUMzQyxPQUFPLHlCQUFpQixDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUNsRCxDQUFDIn0=
|
package/dist/drivers/bullmq.js
CHANGED
|
@@ -69,18 +69,18 @@ class BullMQDriver {
|
|
|
69
69
|
const jobId = crypto.randomUUID();
|
|
70
70
|
const job = await this.queue.add(task.name, task.data, {
|
|
71
71
|
jobId,
|
|
72
|
-
...(task.schedule
|
|
72
|
+
...(typeof task.schedule === 'string'
|
|
73
73
|
? {
|
|
74
74
|
repeat: {
|
|
75
|
-
pattern: task.schedule
|
|
76
|
-
tz: task.
|
|
75
|
+
pattern: task.schedule,
|
|
76
|
+
tz: task.timezone,
|
|
77
77
|
immediately: !!task.immediate,
|
|
78
78
|
},
|
|
79
79
|
}
|
|
80
80
|
: {
|
|
81
|
-
delay: (task.schedule
|
|
82
|
-
? task.schedule.
|
|
83
|
-
: task.schedule
|
|
81
|
+
delay: (task.schedule instanceof Date
|
|
82
|
+
? task.schedule.getTime()
|
|
83
|
+
: task.schedule) - Date.now(),
|
|
84
84
|
}),
|
|
85
85
|
});
|
|
86
86
|
return job.id ?? jobId;
|
|
@@ -107,4 +107,4 @@ class BullMQDriver {
|
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
exports.BullMQDriver = BullMQDriver;
|
|
110
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
110
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVsbG1xLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2RyaXZlcnMvYnVsbG1xLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLG1DQUEwRDtBQUcxRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnQ0c7QUFDSCxNQUFhLFlBQVk7SUFTdkI7Ozs7O09BS0c7SUFDSCxZQUNFLFVBQTZCLEVBQ1osWUFBb0Isa0JBQWtCO1FBQXRDLGNBQVMsR0FBVCxTQUFTLENBQTZCO1FBaEJqRCxXQUFNLEdBQXNCLElBQUksQ0FBQztRQWtCdkMsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLGNBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLEVBQUUsVUFBVSxFQUFFLENBQUMsQ0FBQztRQUN2RCxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksZUFBTSxDQUN0QixJQUFJLENBQUMsU0FBUyxFQUNkLEtBQUssRUFBRSxHQUFHLEVBQUUsRUFBRTtZQUNaLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTTtnQkFBRSxNQUFNLElBQUksS0FBSyxDQUFDLDhCQUE4QixDQUFDLENBQUM7WUFFbEUsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDO2dCQUNoQixJQUFJLEVBQUUsR0FBRyxDQUFDLElBQUk7Z0JBQ2QsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJO2dCQUNkLFNBQVMsRUFBRSxHQUFHLENBQUMsU0FBUzthQUN6QixDQUFDLENBQUM7UUFDTCxDQUFDLEVBQ0QsRUFBRSxVQUFVLEVBQUUsQ0FDZixDQUFDO0lBQ0osQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0ksS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFjO1FBQ2hDLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNsQyxNQUFNLEdBQUcsR0FBRyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRTtZQUNyRCxLQUFLO1lBQ0wsR0FBRyxDQUFDLE9BQU8sSUFBSSxDQUFDLFFBQVEsS0FBSyxRQUFRO2dCQUNuQyxDQUFDLENBQUM7b0JBQ0UsTUFBTSxFQUFFO3dCQUNOLE9BQU8sRUFBRSxJQUFJLENBQUMsUUFBUTt3QkFDdEIsRUFBRSxFQUFFLElBQUksQ0FBQyxRQUFRO3dCQUNqQixXQUFXLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTO3FCQUM5QjtpQkFDRjtnQkFDSCxDQUFDLENBQUM7b0JBQ0UsS0FBSyxFQUNILENBQUMsSUFBSSxDQUFDLFFBQVEsWUFBWSxJQUFJO3dCQUM1QixDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUU7d0JBQ3pCLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRTtpQkFDbEMsQ0FBQztTQUNQLENBQUMsQ0FBQztRQUVILE9BQU8sR0FBRyxDQUFDLEVBQUUsSUFBSSxLQUFLLENBQUM7SUFDekIsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLEtBQUssQ0FBQyxNQUFNLENBQUMsVUFBa0I7UUFDcEMsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUUsRUFBRSxjQUFjLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUNoRSxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksS0FBSyxDQUFDLGFBQWEsQ0FBQyxNQUFrQjtRQUMzQyxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztJQUN2QixDQUFDO0NBQ0Y7QUF4RkQsb0NBd0ZDIn0=
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { TaskDriver, TaskRunner } from '../driver';
|
|
2
|
+
import { TaskData } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* SQLite-based persistent job queue manager for CommandKit tasks.
|
|
5
|
+
*
|
|
6
|
+
* - Jobs are recoverable on restart (pending jobs from the past are run on startup)
|
|
7
|
+
* - Job data is persisted in SQLite
|
|
8
|
+
* - Supports both cron and date-based schedules (uses cron-parser for cron)
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* import { SQLiteDriver } from '@commandkit/tasks/sqlite';
|
|
12
|
+
* import { setDriver } from '@commandkit/tasks';
|
|
13
|
+
*
|
|
14
|
+
* const driver = new SQLiteDriver('./tasks.db');
|
|
15
|
+
* setDriver(driver);
|
|
16
|
+
*/
|
|
17
|
+
export declare class SQLiteDriver implements TaskDriver {
|
|
18
|
+
private runner;
|
|
19
|
+
private db;
|
|
20
|
+
private interval;
|
|
21
|
+
/**
|
|
22
|
+
* Create a new SQLiteDriver instance.
|
|
23
|
+
* @param dbPath Path to the SQLite database file (default: './commandkit-tasks.db'). Use `:memory:` for an in-memory database.
|
|
24
|
+
*/
|
|
25
|
+
constructor(dbPath?: string);
|
|
26
|
+
/**
|
|
27
|
+
* Destroy the SQLite driver and stop the polling loop.
|
|
28
|
+
*/
|
|
29
|
+
destroy(): void;
|
|
30
|
+
/**
|
|
31
|
+
* Initialize the jobs table and start the polling loop.
|
|
32
|
+
*/
|
|
33
|
+
private init;
|
|
34
|
+
/**
|
|
35
|
+
* Schedule a new job.
|
|
36
|
+
* @param task TaskData to schedule
|
|
37
|
+
* @returns The job ID as a string
|
|
38
|
+
*/
|
|
39
|
+
create(task: TaskData): Promise<string>;
|
|
40
|
+
/**
|
|
41
|
+
* Delete a scheduled job by its ID.
|
|
42
|
+
* @param identifier Job ID
|
|
43
|
+
*/
|
|
44
|
+
delete(identifier: string): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Set the task runner function to be called when a job is due.
|
|
47
|
+
* @param runner TaskRunner function
|
|
48
|
+
*/
|
|
49
|
+
setTaskRunner(runner: TaskRunner): Promise<void>;
|
|
50
|
+
/**
|
|
51
|
+
* Poll the database for due jobs and execute them.
|
|
52
|
+
* Handles recovery of missed jobs on restart.
|
|
53
|
+
*/
|
|
54
|
+
private startPolling;
|
|
55
|
+
/**
|
|
56
|
+
* Poll for jobs that are due and execute them.
|
|
57
|
+
*/
|
|
58
|
+
private pollJobs;
|
|
59
|
+
/**
|
|
60
|
+
* Execute a job and reschedule or remove as needed.
|
|
61
|
+
*/
|
|
62
|
+
private executeJob;
|
|
63
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
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.SQLiteDriver = void 0;
|
|
7
|
+
const node_sqlite_1 = require("node:sqlite");
|
|
8
|
+
const cron_parser_1 = __importDefault(require("cron-parser"));
|
|
9
|
+
/**
|
|
10
|
+
* SQLite-based persistent job queue manager for CommandKit tasks.
|
|
11
|
+
*
|
|
12
|
+
* - Jobs are recoverable on restart (pending jobs from the past are run on startup)
|
|
13
|
+
* - Job data is persisted in SQLite
|
|
14
|
+
* - Supports both cron and date-based schedules (uses cron-parser for cron)
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* import { SQLiteDriver } from '@commandkit/tasks/sqlite';
|
|
18
|
+
* import { setDriver } from '@commandkit/tasks';
|
|
19
|
+
*
|
|
20
|
+
* const driver = new SQLiteDriver('./tasks.db');
|
|
21
|
+
* setDriver(driver);
|
|
22
|
+
*/
|
|
23
|
+
class SQLiteDriver {
|
|
24
|
+
/**
|
|
25
|
+
* Create a new SQLiteDriver instance.
|
|
26
|
+
* @param dbPath Path to the SQLite database file (default: './commandkit-tasks.db'). Use `:memory:` for an in-memory database.
|
|
27
|
+
*/
|
|
28
|
+
constructor(dbPath = './commandkit-tasks.db') {
|
|
29
|
+
this.runner = null;
|
|
30
|
+
this.interval = null;
|
|
31
|
+
this.db = new node_sqlite_1.DatabaseSync(dbPath, { open: true });
|
|
32
|
+
this.init();
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Destroy the SQLite driver and stop the polling loop.
|
|
36
|
+
*/
|
|
37
|
+
destroy() {
|
|
38
|
+
this.db.close();
|
|
39
|
+
this.interval && clearInterval(this.interval);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Initialize the jobs table and start the polling loop.
|
|
43
|
+
*/
|
|
44
|
+
init() {
|
|
45
|
+
this.db.exec(`CREATE TABLE IF NOT EXISTS jobs (
|
|
46
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
47
|
+
name TEXT NOT NULL,
|
|
48
|
+
data TEXT,
|
|
49
|
+
schedule_type TEXT NOT NULL,
|
|
50
|
+
schedule_value TEXT NOT NULL,
|
|
51
|
+
timezone TEXT,
|
|
52
|
+
next_run INTEGER,
|
|
53
|
+
status TEXT NOT NULL DEFAULT 'pending',
|
|
54
|
+
created_at INTEGER NOT NULL,
|
|
55
|
+
last_run INTEGER
|
|
56
|
+
)`);
|
|
57
|
+
this.startPolling();
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Schedule a new job.
|
|
61
|
+
* @param task TaskData to schedule
|
|
62
|
+
* @returns The job ID as a string
|
|
63
|
+
*/
|
|
64
|
+
async create(task) {
|
|
65
|
+
const { name, data, schedule, timezone } = task;
|
|
66
|
+
let nextRun;
|
|
67
|
+
let scheduleType;
|
|
68
|
+
let scheduleValue;
|
|
69
|
+
if (typeof schedule === 'string') {
|
|
70
|
+
scheduleType = 'cron';
|
|
71
|
+
scheduleValue = schedule;
|
|
72
|
+
const interval = cron_parser_1.default.parseExpression(schedule, {
|
|
73
|
+
tz: timezone,
|
|
74
|
+
});
|
|
75
|
+
nextRun = interval.next().getTime();
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
scheduleType = 'date';
|
|
79
|
+
scheduleValue = String(schedule);
|
|
80
|
+
nextRun = typeof schedule === 'number' ? schedule : schedule.getTime();
|
|
81
|
+
}
|
|
82
|
+
const stmt = this.db.prepare(`INSERT INTO jobs (name, data, schedule_type, schedule_value, timezone, next_run, status, created_at) VALUES (?, ?, ?, ?, ?, ?, 'pending', ?)`);
|
|
83
|
+
const result = stmt.run(name, JSON.stringify(data ?? {}), scheduleType, scheduleValue, timezone ?? null, nextRun, Date.now());
|
|
84
|
+
if (task.immediate) {
|
|
85
|
+
await this.runner?.({
|
|
86
|
+
name,
|
|
87
|
+
data,
|
|
88
|
+
timestamp: Date.now(),
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
return result.lastInsertRowid.toString();
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Delete a scheduled job by its ID.
|
|
95
|
+
* @param identifier Job ID
|
|
96
|
+
*/
|
|
97
|
+
async delete(identifier) {
|
|
98
|
+
const stmt = this.db.prepare(`DELETE FROM jobs WHERE id = ?`);
|
|
99
|
+
stmt.run(identifier);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Set the task runner function to be called when a job is due.
|
|
103
|
+
* @param runner TaskRunner function
|
|
104
|
+
*/
|
|
105
|
+
async setTaskRunner(runner) {
|
|
106
|
+
this.runner = runner;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Poll the database for due jobs and execute them.
|
|
110
|
+
* Handles recovery of missed jobs on restart.
|
|
111
|
+
*/
|
|
112
|
+
startPolling() {
|
|
113
|
+
if (this.interval)
|
|
114
|
+
clearInterval(this.interval);
|
|
115
|
+
this.interval = setInterval(() => this.pollJobs(), 1000);
|
|
116
|
+
// Run immediately on startup
|
|
117
|
+
this.pollJobs();
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Poll for jobs that are due and execute them.
|
|
121
|
+
*/
|
|
122
|
+
pollJobs() {
|
|
123
|
+
if (!this.runner)
|
|
124
|
+
return;
|
|
125
|
+
const now = Date.now();
|
|
126
|
+
const stmt = this.db.prepare(`SELECT * FROM jobs WHERE status = 'pending' AND next_run <= ?`);
|
|
127
|
+
const rows = stmt.all(now);
|
|
128
|
+
for (const job of rows) {
|
|
129
|
+
this.executeJob(job);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Execute a job and reschedule or remove as needed.
|
|
134
|
+
*/
|
|
135
|
+
async executeJob(job) {
|
|
136
|
+
if (!this.runner)
|
|
137
|
+
return;
|
|
138
|
+
const data = JSON.parse(job.data ?? '{}');
|
|
139
|
+
await this.runner({
|
|
140
|
+
name: job.name,
|
|
141
|
+
data,
|
|
142
|
+
timestamp: Date.now(),
|
|
143
|
+
});
|
|
144
|
+
const now = Date.now();
|
|
145
|
+
if (job.schedule_type === 'cron') {
|
|
146
|
+
let nextRun = null;
|
|
147
|
+
try {
|
|
148
|
+
const interval = cron_parser_1.default.parseExpression(job.schedule_value, {
|
|
149
|
+
tz: job.timezone || undefined,
|
|
150
|
+
});
|
|
151
|
+
// Find the next run after now
|
|
152
|
+
while (true) {
|
|
153
|
+
const candidate = interval.next().getTime();
|
|
154
|
+
if (candidate > now) {
|
|
155
|
+
nextRun = candidate;
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
nextRun = null;
|
|
162
|
+
}
|
|
163
|
+
if (nextRun) {
|
|
164
|
+
const stmt = this.db.prepare(`UPDATE jobs SET next_run = ?, last_run = ? WHERE id = ?`);
|
|
165
|
+
stmt.run(nextRun, now, job.id);
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
const stmt = this.db.prepare(`UPDATE jobs SET status = 'completed', last_run = ? WHERE id = ?`);
|
|
169
|
+
stmt.run(now, job.id);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
const stmt = this.db.prepare(`UPDATE jobs SET status = 'completed', last_run = ? WHERE id = ?`);
|
|
174
|
+
stmt.run(now, job.id);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
exports.SQLiteDriver = SQLiteDriver;
|
|
179
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3FsaXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2RyaXZlcnMvc3FsaXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUVBLDZDQUEyQztBQUMzQyw4REFBcUM7QUFFckM7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUNILE1BQWEsWUFBWTtJQUt2Qjs7O09BR0c7SUFDSCxZQUFZLE1BQU0sR0FBRyx1QkFBdUI7UUFScEMsV0FBTSxHQUFzQixJQUFJLENBQUM7UUFFakMsYUFBUSxHQUEwQixJQUFJLENBQUM7UUFPN0MsSUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLDBCQUFZLENBQUMsTUFBTSxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDbkQsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ2QsQ0FBQztJQUVEOztPQUVHO0lBQ0ksT0FBTztRQUNaLElBQUksQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDaEIsSUFBSSxDQUFDLFFBQVEsSUFBSSxhQUFhLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ2hELENBQUM7SUFFRDs7T0FFRztJQUNLLElBQUk7UUFDVixJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQzs7Ozs7Ozs7Ozs7TUFXWCxDQUFDLENBQUM7UUFDSixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDdEIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxLQUFLLENBQUMsTUFBTSxDQUFDLElBQWM7UUFDekIsTUFBTSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxHQUFHLElBQUksQ0FBQztRQUNoRCxJQUFJLE9BQWUsQ0FBQztRQUNwQixJQUFJLFlBQW9CLENBQUM7UUFDekIsSUFBSSxhQUFxQixDQUFDO1FBRTFCLElBQUksT0FBTyxRQUFRLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDakMsWUFBWSxHQUFHLE1BQU0s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
|
package/dist/task.d.ts
CHANGED
|
@@ -60,6 +60,11 @@ export declare class Task<T extends Record<string, any> = Record<string, any>> {
|
|
|
60
60
|
* @returns true if the task has a date schedule
|
|
61
61
|
*/
|
|
62
62
|
isDate(): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* The timezone for the task schedule.
|
|
65
|
+
* Returns undefined if no timezone is defined.
|
|
66
|
+
*/
|
|
67
|
+
get timezone(): string | undefined;
|
|
63
68
|
/**
|
|
64
69
|
* Determines if the task is ready to be executed.
|
|
65
70
|
*
|
package/dist/task.js
CHANGED
|
@@ -63,7 +63,7 @@ class Task {
|
|
|
63
63
|
* @returns true if the task has a cron schedule
|
|
64
64
|
*/
|
|
65
65
|
isCron() {
|
|
66
|
-
return this.schedule
|
|
66
|
+
return typeof this.schedule === 'string';
|
|
67
67
|
}
|
|
68
68
|
/**
|
|
69
69
|
* Checks if this task uses date-based scheduling.
|
|
@@ -71,7 +71,16 @@ class Task {
|
|
|
71
71
|
* @returns true if the task has a date schedule
|
|
72
72
|
*/
|
|
73
73
|
isDate() {
|
|
74
|
-
|
|
74
|
+
if (this.schedule == null)
|
|
75
|
+
return false;
|
|
76
|
+
return this.schedule instanceof Date || typeof this.schedule === 'number';
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The timezone for the task schedule.
|
|
80
|
+
* Returns undefined if no timezone is defined.
|
|
81
|
+
*/
|
|
82
|
+
get timezone() {
|
|
83
|
+
return this.data.timezone ?? undefined;
|
|
75
84
|
}
|
|
76
85
|
/**
|
|
77
86
|
* Determines if the task is ready to be executed.
|
|
@@ -126,4 +135,4 @@ exports.Task = Task;
|
|
|
126
135
|
function task(data) {
|
|
127
136
|
return new Task(data);
|
|
128
137
|
}
|
|
129
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
138
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFzay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy90YXNrLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQTBJQSxvQkFJQztBQTNJRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXlCRztBQUNILE1BQWEsSUFBSTtJQUNmOzs7O09BSUc7SUFDSCxZQUEyQixJQUF1QjtRQUF2QixTQUFJLEdBQUosSUFBSSxDQUFtQjtJQUFHLENBQUM7SUFFdEQ7OztPQUdHO0lBQ0gsSUFBVyxTQUFTO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksS0FBSyxDQUFDO0lBQ3RDLENBQUM7SUFFRDs7T0FFRztJQUNILElBQVcsSUFBSTtRQUNiLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDeEIsQ0FBQztJQUVEOzs7T0FHRztJQUNILElBQVcsUUFBUTtRQUNqQixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQztJQUNwQyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNJLE1BQU07UUFDWCxPQUFPLE9BQU8sSUFBSSxDQUFDLFFBQVEsS0FBSyxRQUFRLENBQUM7SUFDM0MsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxNQUFNO1FBQ1gsSUFBSSxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUk7WUFBRSxPQUFPLEtBQUssQ0FBQztRQUN4QyxPQUFPLElBQUksQ0FBQyxRQUFRLFlBQVksSUFBSSxJQUFJLE9BQU8sSUFBSSxDQUFDLFFBQVEsS0FBSyxRQUFRLENBQUM7SUFDNUUsQ0FBQztJQUVEOzs7T0FHRztJQUNILElBQVcsUUFBUTtRQUNqQixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxJQUFJLFNBQVMsQ0FBQztJQUN6QyxDQUFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDSSxLQUFLLENBQUMsT0FBTyxDQUFDLEdBQW1CO1FBQ3RDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUM7SUFDMUMsQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0ksS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFtQjtRQUN0QyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQy9CLENBQUM7Q0FDRjtBQW5GRCxvQkFtRkM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F1Qkc7QUFDSCxTQUFnQixJQUFJLENBQ2xCLElBQXVCO0lBRXZCLE9BQU8sSUFBSSxJQUFJLENBQUksSUFBSSxDQUFDLENBQUM7QUFDM0IsQ0FBQyJ9
|
package/dist/types.d.ts
CHANGED
|
@@ -5,21 +5,7 @@ import { TaskContext } from './context';
|
|
|
5
5
|
* Tasks can be scheduled using either cron expressions or specific dates/timestamps.
|
|
6
6
|
* The timezone is optional and defaults to the system timezone.
|
|
7
7
|
*/
|
|
8
|
-
export type TaskSchedule =
|
|
9
|
-
/** Schedule type using cron expressions */
|
|
10
|
-
type: 'cron';
|
|
11
|
-
/** Optional timezone for the cron schedule (e.g., 'UTC', 'America/New_York') */
|
|
12
|
-
timezone?: string;
|
|
13
|
-
/** Cron expression (e.g., '0 0 * * *' for daily at midnight) */
|
|
14
|
-
value: string;
|
|
15
|
-
} | {
|
|
16
|
-
/** Schedule type using a specific date or timestamp */
|
|
17
|
-
type: 'date';
|
|
18
|
-
/** Optional timezone for the date schedule */
|
|
19
|
-
timezone?: string;
|
|
20
|
-
/** Date object or Unix timestamp in milliseconds */
|
|
21
|
-
value: Date | number;
|
|
22
|
-
};
|
|
8
|
+
export type TaskSchedule = string | Date | number;
|
|
23
9
|
/**
|
|
24
10
|
* Defines a task with its execution logic and scheduling.
|
|
25
11
|
*
|
|
@@ -31,6 +17,8 @@ export interface TaskDefinition<T extends Record<string, any> = Record<string, a
|
|
|
31
17
|
name: string;
|
|
32
18
|
/** Optional schedule configuration for recurring or delayed execution */
|
|
33
19
|
schedule?: TaskSchedule;
|
|
20
|
+
/** Optional timezone for the schedule */
|
|
21
|
+
timezone?: string;
|
|
34
22
|
/** Whether the task should run immediately when created (only for cron tasks) */
|
|
35
23
|
immediate?: boolean;
|
|
36
24
|
/**
|
|
@@ -56,6 +44,8 @@ export interface TaskData<T extends Record<string, any> = Record<string, any>> {
|
|
|
56
44
|
data: T;
|
|
57
45
|
/** Schedule configuration for when the task should run */
|
|
58
46
|
schedule: TaskSchedule;
|
|
47
|
+
/** Optional timezone for the schedule */
|
|
48
|
+
timezone?: string;
|
|
59
49
|
/** Whether the task should run immediately when created */
|
|
60
50
|
immediate?: boolean;
|
|
61
51
|
}
|
|
@@ -71,7 +61,7 @@ export type PartialTaskData<T extends Record<string, any> = Record<string, any>>
|
|
|
71
61
|
* This includes the task metadata and execution timestamp, but excludes
|
|
72
62
|
* scheduling information since the task is already being executed.
|
|
73
63
|
*/
|
|
74
|
-
export type TaskExecutionData = Omit<TaskData, 'schedule' | 'immediate'> & {
|
|
64
|
+
export type TaskExecutionData = Omit<TaskData, 'schedule' | 'immediate' | 'timezone'> & {
|
|
75
65
|
/** Unix timestamp when the task execution started */
|
|
76
66
|
timestamp: number;
|
|
77
67
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@commandkit/tasks",
|
|
3
|
-
"version": "0.0.0-dev.
|
|
3
|
+
"version": "0.0.0-dev.20250726103524",
|
|
4
4
|
"description": "Task management plugin for CommandKit",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
"import": "./dist/drivers/bullmq.js",
|
|
16
16
|
"require": "./dist/drivers/bullmq.js"
|
|
17
17
|
},
|
|
18
|
-
"./
|
|
19
|
-
"types": "./dist/drivers/
|
|
20
|
-
"import": "./dist/drivers/
|
|
21
|
-
"require": "./dist/drivers/
|
|
18
|
+
"./sqlite": {
|
|
19
|
+
"types": "./dist/drivers/sqlite.d.ts",
|
|
20
|
+
"import": "./dist/drivers/sqlite.js",
|
|
21
|
+
"require": "./dist/drivers/sqlite.js"
|
|
22
22
|
}
|
|
23
23
|
},
|
|
24
24
|
"files": [
|
|
@@ -44,10 +44,9 @@
|
|
|
44
44
|
"homepage": "https://github.com/underctrl-io/commandkit#readme",
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"bullmq": "^5.56.5",
|
|
47
|
-
"hypercron": "^0.1.0",
|
|
48
47
|
"typescript": "^5.8.3",
|
|
49
|
-
"tsconfig": "0.0.0-dev.
|
|
50
|
-
"commandkit": "1.0.0-dev.
|
|
48
|
+
"tsconfig": "0.0.0-dev.20250726103524",
|
|
49
|
+
"commandkit": "1.0.0-dev.20250726103524"
|
|
51
50
|
},
|
|
52
51
|
"dependencies": {
|
|
53
52
|
"cron-parser": "^4.9.0"
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { TaskDriver, TaskRunner } from '../driver';
|
|
2
|
-
import { TaskData } from '../types';
|
|
3
|
-
/**
|
|
4
|
-
* HyperCron-based task driver for lightweight task scheduling.
|
|
5
|
-
*
|
|
6
|
-
* This driver uses HyperCron to provide simple, in-memory task scheduling.
|
|
7
|
-
* It's ideal for single-instance applications or development environments
|
|
8
|
-
* where you don't need distributed task scheduling.
|
|
9
|
-
*
|
|
10
|
-
* **Requirements**: Requires the `hypercron` package to be installed.
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```ts
|
|
14
|
-
* import { HyperCronDriver } from '@commandkit/tasks/hypercron';
|
|
15
|
-
* import { setDriver } from '@commandkit/tasks';
|
|
16
|
-
*
|
|
17
|
-
* const driver = new HyperCronDriver();
|
|
18
|
-
* setDriver(driver);
|
|
19
|
-
* ```
|
|
20
|
-
*
|
|
21
|
-
* @example
|
|
22
|
-
* ```ts
|
|
23
|
-
* // With custom cron service
|
|
24
|
-
* import { cronService } from 'hypercron';
|
|
25
|
-
*
|
|
26
|
-
* const customService = cronService.create({
|
|
27
|
-
* // Custom configuration
|
|
28
|
-
* });
|
|
29
|
-
*
|
|
30
|
-
* const driver = new HyperCronDriver(customService);
|
|
31
|
-
* setDriver(driver);
|
|
32
|
-
* ```
|
|
33
|
-
*/
|
|
34
|
-
export declare class HyperCronDriver implements TaskDriver {
|
|
35
|
-
private readonly service;
|
|
36
|
-
private runner;
|
|
37
|
-
/**
|
|
38
|
-
* Creates a new HyperCron driver instance.
|
|
39
|
-
*
|
|
40
|
-
* @param service - Optional custom cron service instance, defaults to the global cronService
|
|
41
|
-
*/
|
|
42
|
-
constructor(service?: import("hypercron").CronService);
|
|
43
|
-
/**
|
|
44
|
-
* Creates a new scheduled task in HyperCron.
|
|
45
|
-
*
|
|
46
|
-
* This schedules the task using the HyperCron service and starts the service
|
|
47
|
-
* if it's not already running.
|
|
48
|
-
*
|
|
49
|
-
* @param task - The task data containing name, schedule, and custom data
|
|
50
|
-
* @returns A unique schedule identifier
|
|
51
|
-
*/
|
|
52
|
-
create(task: TaskData): Promise<string>;
|
|
53
|
-
/**
|
|
54
|
-
* Deletes a scheduled task from HyperCron.
|
|
55
|
-
*
|
|
56
|
-
* This cancels the scheduled task and removes it from the cron service.
|
|
57
|
-
*
|
|
58
|
-
* @param identifier - The schedule identifier to delete
|
|
59
|
-
*/
|
|
60
|
-
delete(identifier: string): Promise<void>;
|
|
61
|
-
/**
|
|
62
|
-
* Sets the task execution runner function.
|
|
63
|
-
*
|
|
64
|
-
* This function will be called by the HyperCron service when a task is due for execution.
|
|
65
|
-
*
|
|
66
|
-
* @param runner - The function to call when a task should be executed
|
|
67
|
-
*/
|
|
68
|
-
setTaskRunner(runner: TaskRunner): Promise<void>;
|
|
69
|
-
}
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.HyperCronDriver = void 0;
|
|
4
|
-
const hypercron_1 = require("hypercron");
|
|
5
|
-
/**
|
|
6
|
-
* HyperCron-based task driver for lightweight task scheduling.
|
|
7
|
-
*
|
|
8
|
-
* This driver uses HyperCron to provide simple, in-memory task scheduling.
|
|
9
|
-
* It's ideal for single-instance applications or development environments
|
|
10
|
-
* where you don't need distributed task scheduling.
|
|
11
|
-
*
|
|
12
|
-
* **Requirements**: Requires the `hypercron` package to be installed.
|
|
13
|
-
*
|
|
14
|
-
* @example
|
|
15
|
-
* ```ts
|
|
16
|
-
* import { HyperCronDriver } from '@commandkit/tasks/hypercron';
|
|
17
|
-
* import { setDriver } from '@commandkit/tasks';
|
|
18
|
-
*
|
|
19
|
-
* const driver = new HyperCronDriver();
|
|
20
|
-
* setDriver(driver);
|
|
21
|
-
* ```
|
|
22
|
-
*
|
|
23
|
-
* @example
|
|
24
|
-
* ```ts
|
|
25
|
-
* // With custom cron service
|
|
26
|
-
* import { cronService } from 'hypercron';
|
|
27
|
-
*
|
|
28
|
-
* const customService = cronService.create({
|
|
29
|
-
* // Custom configuration
|
|
30
|
-
* });
|
|
31
|
-
*
|
|
32
|
-
* const driver = new HyperCronDriver(customService);
|
|
33
|
-
* setDriver(driver);
|
|
34
|
-
* ```
|
|
35
|
-
*/
|
|
36
|
-
class HyperCronDriver {
|
|
37
|
-
/**
|
|
38
|
-
* Creates a new HyperCron driver instance.
|
|
39
|
-
*
|
|
40
|
-
* @param service - Optional custom cron service instance, defaults to the global cronService
|
|
41
|
-
*/
|
|
42
|
-
constructor(service = hypercron_1.cronService) {
|
|
43
|
-
this.service = service;
|
|
44
|
-
this.runner = null;
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Creates a new scheduled task in HyperCron.
|
|
48
|
-
*
|
|
49
|
-
* This schedules the task using the HyperCron service and starts the service
|
|
50
|
-
* if it's not already running.
|
|
51
|
-
*
|
|
52
|
-
* @param task - The task data containing name, schedule, and custom data
|
|
53
|
-
* @returns A unique schedule identifier
|
|
54
|
-
*/
|
|
55
|
-
async create(task) {
|
|
56
|
-
const id = await this.service.schedule(task.schedule.value, task.name, async () => {
|
|
57
|
-
if (!this.runner)
|
|
58
|
-
throw new Error('Task runner has not been set');
|
|
59
|
-
await this.runner({
|
|
60
|
-
name: task.name,
|
|
61
|
-
data: task.data,
|
|
62
|
-
timestamp: Date.now(),
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
await this.service.start();
|
|
66
|
-
return id;
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Deletes a scheduled task from HyperCron.
|
|
70
|
-
*
|
|
71
|
-
* This cancels the scheduled task and removes it from the cron service.
|
|
72
|
-
*
|
|
73
|
-
* @param identifier - The schedule identifier to delete
|
|
74
|
-
*/
|
|
75
|
-
async delete(identifier) {
|
|
76
|
-
await this.service.cancel(identifier);
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Sets the task execution runner function.
|
|
80
|
-
*
|
|
81
|
-
* This function will be called by the HyperCron service when a task is due for execution.
|
|
82
|
-
*
|
|
83
|
-
* @param runner - The function to call when a task should be executed
|
|
84
|
-
*/
|
|
85
|
-
async setTaskRunner(runner) {
|
|
86
|
-
this.runner = runner;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
exports.HyperCronDriver = HyperCronDriver;
|
|
90
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHlwZXJjcm9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2RyaXZlcnMvaHlwZXJjcm9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHlDQUF3QztBQUl4Qzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBOEJHO0FBQ0gsTUFBYSxlQUFlO0lBRzFCOzs7O09BSUc7SUFDSCxZQUFvQyxVQUFVLHVCQUFXO1FBQXJCLFlBQU8sR0FBUCxPQUFPLENBQWM7UUFQakQsV0FBTSxHQUFzQixJQUFJLENBQUM7SUFPbUIsQ0FBQztJQUU3RDs7Ozs7Ozs7T0FRRztJQUNJLEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBYztRQUNoQyxNQUFNLEVBQUUsR0FBRyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUNwQyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssRUFDbkIsSUFBSSxDQUFDLElBQUksRUFDVCxLQUFLLElBQUksRUFBRTtZQUNULElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTTtnQkFBRSxNQUFNLElBQUksS0FBSyxDQUFDLDhCQUE4QixDQUFDLENBQUM7WUFFbEUsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDO2dCQUNoQixJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUk7Z0JBQ2YsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJO2dCQUNmLFNBQVMsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFO2FBQ3RCLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FDRixDQUFDO1FBRUYsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBRTNCLE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLEtBQUssQ0FBQyxNQUFNLENBQUMsVUFBa0I7UUFDcEMsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksS0FBSyxDQUFDLGFBQWEsQ0FBQyxNQUFrQjtRQUMzQyxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztJQUN2QixDQUFDO0NBQ0Y7QUE1REQsMENBNERDIn0=
|