Skip to content

Commit ef85fc5

Browse files
committed
fix: allow data type defintions for jobs
1 parent 3bd90dc commit ef85fc5

8 files changed

+182
-105
lines changed

package.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
{
22
"name": "@hokify/agenda",
3-
"version": "4.0.2",
3+
"version": "4.0.4",
44
"description": "Light weight job scheduler for Node.js",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",
7+
"publishConfig": {
8+
"access": "public"
9+
},
710
"files": [
811
"dist"
912
],

src/Job.ts

+41-18
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { parsePriority } from './utils/priority';
44
import type { Agenda } from './index';
55
import { computeFromInterval, computeFromRepeatAt } from './utils/nextRunAt';
66
import { IJobParameters } from './types/JobParameters';
7+
import type { DefinitionProcessor } from './types/JobDefinition';
78

89
const log = debug('agenda:job');
910

@@ -13,12 +14,31 @@ const log = debug('agenda:job');
1314
* @property {Object} agenda - The Agenda instance
1415
* @property {Object} attrs
1516
*/
16-
export class Job {
17-
readonly attrs: IJobParameters;
17+
export class Job<DATA = any | void> {
18+
readonly attrs: IJobParameters<DATA>;
1819

20+
constructor(
21+
agenda: Agenda,
22+
args: Partial<IJobParameters<void>> & {
23+
name: string;
24+
type: 'normal' | 'single';
25+
}
26+
);
27+
constructor(
28+
agenda: Agenda,
29+
args: Partial<IJobParameters<DATA>> & {
30+
name: string;
31+
type: 'normal' | 'single';
32+
data: DATA;
33+
}
34+
);
1935
constructor(
2036
readonly agenda: Agenda,
21-
args: Partial<IJobParameters> & { name: string; type: 'normal' | 'single' }
37+
args: Partial<IJobParameters<DATA>> & {
38+
name: string;
39+
type: 'normal' | 'single';
40+
data: any;
41+
}
2242
) {
2343
// Remove special args
2444

@@ -35,10 +55,11 @@ export class Job {
3555
};
3656
}
3757

38-
toJson() {
58+
toJson(): Partial<IJobParameters> {
3959
const attrs = this.attrs || {};
4060
const result = {};
4161

62+
// eslint-disable-next-line no-restricted-syntax
4263
for (const prop in attrs) {
4364
if ({}.hasOwnProperty.call(attrs, prop)) {
4465
result[prop] = attrs[prop];
@@ -155,18 +176,17 @@ export class Job {
155176
return this.agenda.db.saveJob(this);
156177
}
157178

158-
remove() {
179+
remove(): Promise<number> {
159180
return this.agenda.cancel({ _id: this.attrs._id });
160181
}
161182

162-
async touch(progress?: number) {
163-
// eslint-disable-next-line prefer-rest-params
183+
async touch(progress?: number): Promise<void> {
164184
this.attrs.lockedAt = new Date();
165185
this.attrs.progress = progress;
166-
return this.save();
186+
await this.save();
167187
}
168188

169-
computeNextRunAt() {
189+
private computeNextRunAt() {
170190
try {
171191
if (this.attrs.repeatInterval) {
172192
this.attrs.nextRunAt = computeFromInterval(this.attrs);
@@ -222,23 +242,26 @@ export class Job {
222242
log('[%s:%s] process function being called', this.attrs.name, this.attrs._id);
223243
await new Promise((resolve, reject) => {
224244
try {
225-
const result = definition.fn(this, err => {
226-
if (err) {
227-
reject(err);
228-
return;
245+
const result = (definition.fn as DefinitionProcessor<DATA, (err?) => void>)(
246+
this,
247+
err => {
248+
if (err) {
249+
reject(err);
250+
return;
251+
}
252+
resolve();
229253
}
230-
resolve();
231-
});
254+
);
232255
if (this.isPromise(result)) {
233-
result.catch(err => reject(err));
256+
(result as any).catch(err => reject(err));
234257
}
235258
} catch (err) {
236259
reject(err);
237260
}
238261
});
239262
} else {
240263
log('[%s:%s] process function being called', this.attrs.name, this.attrs._id);
241-
await definition.fn(this);
264+
await (definition.fn as DefinitionProcessor<DATA, void>)(this);
242265
}
243266

244267
this.attrs.lastFinishedAt = new Date();
@@ -271,6 +294,6 @@ export class Job {
271294
}
272295

273296
private isPromise(value): value is Promise<void> {
274-
return Boolean(value && typeof value.then === 'function');
297+
return !!(value && typeof value.then === 'function');
275298
}
276299
}

src/JobDbRepository.ts

+12-11
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
UpdateQuery,
99
ObjectId
1010
} from 'mongodb';
11-
import { Job } from './Job';
11+
import type { Job } from './Job';
1212
import { hasMongoProtocol } from './utils/mongodb';
1313
import type { Agenda } from './index';
1414
import { IDatabaseOptions, IDbConfig, IMongoOptions } from './types/DbOptions';
@@ -207,22 +207,23 @@ export class JobDbRepository {
207207
* @param {Job} job job to save into MongoDB
208208
* @returns {Promise} resolves when job is saved or errors
209209
*/
210-
async saveJob(job: Job) {
210+
async saveJob<T = any>(job: Job<T>): Promise<Job<T>> {
211211
try {
212212
log('attempting to save a job into Agenda instance');
213213

214214
// Grab information needed to save job but that we don't want to persist in MongoDB
215215
const id = job.attrs._id;
216-
const { unique, uniqueOpts } = job.attrs;
216+
// const { unique, uniqueOpts } = job.attrs;
217217

218218
// Store job as JSON and remove props we don't want to store from object
219-
const props: Partial<IJobParameters> = job.toJson();
220-
delete props._id;
221-
delete props.unique;
222-
delete props.uniqueOpts;
219+
// _id, unique, uniqueOpts
220+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
221+
const { _id, unique, uniqueOpts, ...props } = {
222+
...job.toJson(),
223+
// Store name of agenda queue as last modifier in job data
224+
lastModifiedBy: this.agenda.attrs.name
225+
};
223226

224-
// Store name of agenda queue as last modifier in job data
225-
props.lastModifiedBy = this.agenda.attrs.name;
226227
log('[job %s] set job props: \n%O', id, props);
227228

228229
// Grab current time and set default query options for MongoDB
@@ -291,11 +292,11 @@ export class JobDbRepository {
291292
return this.processDbResult(job, result.value);
292293
}
293294

294-
if (unique) {
295+
if (job.attrs.unique) {
295296
// If we want the job to be unique, then we can upsert based on the 'unique' query object that was passed in
296297
const query: FilterQuery<any> = job.attrs.unique;
297298
query.name = props.name;
298-
if (uniqueOpts?.insertOnly) {
299+
if (job.attrs.uniqueOpts?.insertOnly) {
299300
update = { $setOnInsert: props };
300301
}
301302

src/JobProcessor.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export class JobProcessor {
2121
| undefined;
2222
} = {};
2323

24-
getStatus() {
24+
async getStatus() {
2525
return {
2626
jobStatus: this.jobStatus,
2727
runningJobs: this.runningJobs.length,

0 commit comments

Comments
 (0)