@tsed/agenda 8.29.0 → 8.30.0
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/lib/esm/decorators/{agenda.js → jobController.js} +0 -4
- package/lib/esm/index.js +1 -1
- package/lib/esm/services/AgendaService.js +17 -16
- package/lib/types/decorators/{agenda.d.ts → jobController.d.ts} +0 -4
- package/lib/types/index.d.ts +1 -1
- package/lib/types/interfaces/AgendaStore.d.ts +12 -3
- package/lib/types/interfaces/interfaces.d.ts +9 -4
- package/lib/types/services/AgendaService.d.ts +0 -5
- package/package.json +11 -8
- package/readme.md +66 -17
package/lib/esm/index.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* @file Automatically generated by @tsed/barrels.
|
|
3
3
|
*/
|
|
4
4
|
export * from "./constants/constants.js";
|
|
5
|
-
export * from "./decorators/agenda.js";
|
|
6
5
|
export * from "./decorators/define.js";
|
|
7
6
|
export * from "./decorators/every.js";
|
|
7
|
+
export * from "./decorators/jobController.js";
|
|
8
8
|
export * from "./interfaces/AgendaStore.js";
|
|
9
9
|
export * from "./interfaces/interfaces.js";
|
|
10
10
|
export * from "./services/AgendaService.js";
|
|
@@ -4,7 +4,11 @@ import { Agenda } from "agenda";
|
|
|
4
4
|
import { v4 as uuid } from "uuid";
|
|
5
5
|
import { PROVIDER_TYPE_AGENDA } from "../constants/constants.js";
|
|
6
6
|
function getOpts() {
|
|
7
|
-
return constant("agenda",
|
|
7
|
+
return constant("agenda", false);
|
|
8
|
+
}
|
|
9
|
+
function getEnabledAgendaOptions(settings) {
|
|
10
|
+
const { enabled, disableJobProcessing, drainJobsBeforeClose, ...agendaOptions } = settings;
|
|
11
|
+
return agendaOptions;
|
|
8
12
|
}
|
|
9
13
|
function addAgendaDefinitionsForProvider(agenda, provider) {
|
|
10
14
|
const store = provider.store.get("agenda", {});
|
|
@@ -13,9 +17,11 @@ function addAgendaDefinitionsForProvider(agenda, provider) {
|
|
|
13
17
|
}
|
|
14
18
|
Object.entries(store.define).forEach(([propertyKey, { name, ...options }]) => {
|
|
15
19
|
const instance = injector().get(provider.token);
|
|
16
|
-
const jobProcessor =
|
|
20
|
+
const jobProcessor = async (job) => {
|
|
21
|
+
return Promise.resolve(instance[propertyKey].call(instance, job));
|
|
22
|
+
};
|
|
17
23
|
const jobName = getNameForJob(propertyKey, store.namespace, name);
|
|
18
|
-
agenda.define(jobName,
|
|
24
|
+
agenda.define(jobName, jobProcessor, options);
|
|
19
25
|
});
|
|
20
26
|
}
|
|
21
27
|
async function scheduleJobsForProvider(agenda, provider) {
|
|
@@ -35,7 +41,7 @@ function getNameForJob(propertyKey, namespace, customName) {
|
|
|
35
41
|
}
|
|
36
42
|
async function afterListen(agenda) {
|
|
37
43
|
const opts = getOpts();
|
|
38
|
-
if (opts.enabled) {
|
|
44
|
+
if (opts && opts.enabled) {
|
|
39
45
|
const providers = injector().getProviders(PROVIDER_TYPE_AGENDA);
|
|
40
46
|
if (!opts.disableJobProcessing) {
|
|
41
47
|
logger().info({
|
|
@@ -58,7 +64,7 @@ async function afterListen(agenda) {
|
|
|
58
64
|
}
|
|
59
65
|
async function onDestroy(agenda) {
|
|
60
66
|
const opts = getOpts();
|
|
61
|
-
if (opts.enabled) {
|
|
67
|
+
if (opts && opts.enabled) {
|
|
62
68
|
if (opts.drainJobsBeforeClose && "drain" in agenda) {
|
|
63
69
|
logger().info({
|
|
64
70
|
event: "AGENDA_DRAIN",
|
|
@@ -73,15 +79,14 @@ async function onDestroy(agenda) {
|
|
|
73
79
|
});
|
|
74
80
|
await agenda.stop();
|
|
75
81
|
}
|
|
76
|
-
await agenda.close({ force: true });
|
|
77
82
|
logger().info({ event: "AGENDA_STOP", message: "Agenda stopped" });
|
|
78
83
|
}
|
|
79
84
|
}
|
|
80
85
|
export const AgendaService = injectable(Agenda)
|
|
81
86
|
.factory(() => {
|
|
82
87
|
const opts = getOpts();
|
|
83
|
-
if (opts.enabled) {
|
|
84
|
-
const agenda = new Agenda(opts);
|
|
88
|
+
if (opts && opts.enabled) {
|
|
89
|
+
const agenda = new Agenda(getEnabledAgendaOptions(opts));
|
|
85
90
|
return new Proxy(agenda, {
|
|
86
91
|
set(target, prop, value) {
|
|
87
92
|
return Reflect.set(target, prop, value);
|
|
@@ -94,14 +99,14 @@ export const AgendaService = injectable(Agenda)
|
|
|
94
99
|
return Reflect.get(target, "define", target);
|
|
95
100
|
}
|
|
96
101
|
if (prop === "define") {
|
|
97
|
-
return (name,
|
|
98
|
-
return target["define"](name,
|
|
102
|
+
return (name, processor, options) => {
|
|
103
|
+
return target["define"](name, async (job) => {
|
|
99
104
|
const $ctx = new DIContext({
|
|
100
105
|
id: uuid()
|
|
101
106
|
});
|
|
102
107
|
$ctx.set("job", job);
|
|
103
|
-
return runInContext($ctx, () => processor(job));
|
|
104
|
-
});
|
|
108
|
+
return Promise.resolve(runInContext($ctx, () => processor(job)));
|
|
109
|
+
}, options);
|
|
105
110
|
};
|
|
106
111
|
}
|
|
107
112
|
return Reflect.get(target, prop, target);
|
|
@@ -115,7 +120,3 @@ export const AgendaService = injectable(Agenda)
|
|
|
115
120
|
$onDestroy: onDestroy
|
|
116
121
|
})
|
|
117
122
|
.token();
|
|
118
|
-
/**
|
|
119
|
-
* @deprecated Use `Agenda` from `agenda` instead.
|
|
120
|
-
*/
|
|
121
|
-
export const AgendaModule = Agenda;
|
package/lib/types/index.d.ts
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* @file Automatically generated by @tsed/barrels.
|
|
3
3
|
*/
|
|
4
4
|
export * from "./constants/constants.js";
|
|
5
|
-
export * from "./decorators/agenda.js";
|
|
6
5
|
export * from "./decorators/define.js";
|
|
7
6
|
export * from "./decorators/every.js";
|
|
7
|
+
export * from "./decorators/jobController.js";
|
|
8
8
|
export * from "./interfaces/AgendaStore.js";
|
|
9
9
|
export * from "./interfaces/interfaces.js";
|
|
10
10
|
export * from "./services/AgendaService.js";
|
|
@@ -1,8 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { type JobDefinition } from "agenda";
|
|
2
|
+
type AgendaJobOptions = {
|
|
3
|
+
timezone?: string;
|
|
4
|
+
skipImmediate?: boolean;
|
|
5
|
+
forkMode?: boolean;
|
|
6
|
+
startDate?: Date | string;
|
|
7
|
+
endDate?: Date | string;
|
|
8
|
+
skipDays?: number[];
|
|
9
|
+
};
|
|
10
|
+
export interface DefineOptions extends Partial<Pick<JobDefinition, "lockLimit" | "lockLifetime" | "concurrency" | "backoff" | "removeOnComplete" | "logging" | "priority">> {
|
|
3
11
|
name?: string;
|
|
4
12
|
}
|
|
5
|
-
export type EveryOptions =
|
|
13
|
+
export type EveryOptions = AgendaJobOptions & DefineOptions;
|
|
6
14
|
export interface AgendaStore {
|
|
7
15
|
namespace?: string;
|
|
8
16
|
define?: {
|
|
@@ -14,3 +22,4 @@ export interface AgendaStore {
|
|
|
14
22
|
};
|
|
15
23
|
};
|
|
16
24
|
}
|
|
25
|
+
export {};
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
enabled?: boolean;
|
|
1
|
+
import { type AgendaOptions } from "agenda";
|
|
2
|
+
type CommonSettings = {
|
|
4
3
|
disableJobProcessing?: boolean;
|
|
5
4
|
drainJobsBeforeClose?: boolean;
|
|
6
|
-
};
|
|
5
|
+
} & AgendaOptions;
|
|
6
|
+
export type AgendaSettings = ({
|
|
7
|
+
enabled: false;
|
|
8
|
+
} & Partial<CommonSettings>) | ({
|
|
9
|
+
enabled?: true;
|
|
10
|
+
} & CommonSettings);
|
|
7
11
|
declare global {
|
|
8
12
|
namespace TsED {
|
|
9
13
|
interface Configuration {
|
|
@@ -11,3 +15,4 @@ declare global {
|
|
|
11
15
|
}
|
|
12
16
|
}
|
|
13
17
|
}
|
|
18
|
+
export {};
|
|
@@ -6,8 +6,3 @@ export declare const AgendaService: {
|
|
|
6
6
|
* @deprecated Use `Agenda` from `agenda` instead.
|
|
7
7
|
*/
|
|
8
8
|
export type AgendaService = Agenda;
|
|
9
|
-
/**
|
|
10
|
-
* @deprecated Use `Agenda` from `agenda` instead.
|
|
11
|
-
*/
|
|
12
|
-
export declare const AgendaModule: typeof Agenda;
|
|
13
|
-
export type AgendaModule = Agenda;
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@tsed/agenda",
|
|
3
3
|
"description": "Agenda package for Ts.ED framework",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "8.
|
|
5
|
+
"version": "8.30.0",
|
|
6
6
|
"source": "./src/index.ts",
|
|
7
7
|
"main": "./lib/esm/index.js",
|
|
8
8
|
"module": "./lib/esm/index.js",
|
|
@@ -26,18 +26,21 @@
|
|
|
26
26
|
"tslib": ">=2.7.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@
|
|
30
|
-
"@tsed/
|
|
31
|
-
"@tsed/
|
|
32
|
-
"@tsed/
|
|
33
|
-
"@tsed/
|
|
34
|
-
"
|
|
29
|
+
"@agendajs/mongo-backend": "^4.0.2",
|
|
30
|
+
"@tsed/barrels": "8.30.0",
|
|
31
|
+
"@tsed/core": "8.30.0",
|
|
32
|
+
"@tsed/di": "8.30.0",
|
|
33
|
+
"@tsed/platform-http": "8.30.0",
|
|
34
|
+
"@tsed/testcontainers-mongo": "8.30.0",
|
|
35
|
+
"@tsed/typescript": "8.30.0",
|
|
36
|
+
"agenda": "^6.2.5",
|
|
35
37
|
"eslint": "9.12.0",
|
|
38
|
+
"mongodb": "^6.21.0",
|
|
36
39
|
"typescript": "6.0.2",
|
|
37
40
|
"vitest": "4.1.4"
|
|
38
41
|
},
|
|
39
42
|
"peerDependencies": {
|
|
40
|
-
"agenda": "
|
|
43
|
+
"agenda": "^6.2.5"
|
|
41
44
|
},
|
|
42
45
|
"repository": "https://github.com/tsedio/tsed",
|
|
43
46
|
"bugs": {
|
package/readme.md
CHANGED
|
@@ -32,7 +32,7 @@ A package of Ts.ED framework. See website: https://tsed.dev
|
|
|
32
32
|
|
|
33
33
|
## Feature
|
|
34
34
|
|
|
35
|
-
Currently, `@tsed/agenda` allows you to decorate classes with `@
|
|
35
|
+
Currently, `@tsed/agenda` allows you to decorate classes with `@JobsController` and
|
|
36
36
|
corresponding methods to have them picked up by the Agenda library to be
|
|
37
37
|
scheduled automatically (`@Every`) or programmatically (`@Define`) via the AgendaService.
|
|
38
38
|
|
|
@@ -43,8 +43,37 @@ For more information about Agenda look at the documentation [here](https://githu
|
|
|
43
43
|
To begin, install the Agenda module for Ts.ED:
|
|
44
44
|
|
|
45
45
|
```bash
|
|
46
|
-
npm install --save @tsed/agenda
|
|
47
|
-
|
|
46
|
+
npm install --save @tsed/agenda agenda @agendajs/mongo-backend
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Migration note
|
|
50
|
+
|
|
51
|
+
`@tsed/agenda` now targets Agenda v6.
|
|
52
|
+
|
|
53
|
+
- `agenda.backend` is required when the module is enabled
|
|
54
|
+
- top-level `db`, `mongo`, and `repository` configuration are no longer supported
|
|
55
|
+
- `ensureIndex` and `sort` move into `new MongoBackend(...)`
|
|
56
|
+
- sort directions use `"asc"` / `"desc"` instead of `1` / `-1`
|
|
57
|
+
- `@Agenda()` has been removed in favor of `@JobsController()`
|
|
58
|
+
- `AgendaModule` has been removed; inject `Agenda` from `agenda`
|
|
59
|
+
|
|
60
|
+
```diff
|
|
61
|
+
import {Configuration} from "@tsed/di";
|
|
62
|
+
import "@tsed/agenda";
|
|
63
|
+
+import {MongoBackend} from "@agendajs/mongo-backend";
|
|
64
|
+
|
|
65
|
+
@Configuration({
|
|
66
|
+
agenda: {
|
|
67
|
+
enabled: true,
|
|
68
|
+
- db: {
|
|
69
|
+
- address: mongoConnectionString
|
|
70
|
+
- }
|
|
71
|
+
+ backend: new MongoBackend({
|
|
72
|
+
+ address: mongoConnectionString
|
|
73
|
+
+ })
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
export class Server {}
|
|
48
77
|
```
|
|
49
78
|
|
|
50
79
|
## Configure your server
|
|
@@ -54,18 +83,23 @@ Import `@tsed/agenda` in your Server:
|
|
|
54
83
|
```typescript
|
|
55
84
|
import {Configuration} from "@tsed/di";
|
|
56
85
|
import "@tsed/agenda"; // import agenda ts.ed module
|
|
86
|
+
import {MongoBackend} from "@agendajs/mongo-backend";
|
|
57
87
|
|
|
58
88
|
const mongoConnectionString = "mongodb://127.0.0.1/agenda";
|
|
59
89
|
|
|
60
90
|
@Configuration({
|
|
61
91
|
agenda: {
|
|
62
92
|
enabled: true, // Enable Agenda jobs for this instance.
|
|
63
|
-
//
|
|
93
|
+
// drainJobsBeforeClose: true, // Wait for jobs to finish before stopping the agenda process.
|
|
64
94
|
// disableJobProcessing: true, // Prevents jobs from being processed.
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
95
|
+
backend: new MongoBackend({
|
|
96
|
+
address: mongoConnectionString,
|
|
97
|
+
ensureIndex: true,
|
|
98
|
+
sort: {
|
|
99
|
+
nextRunAt: "asc",
|
|
100
|
+
priority: "desc"
|
|
101
|
+
}
|
|
102
|
+
})
|
|
69
103
|
}
|
|
70
104
|
})
|
|
71
105
|
export class Server {}
|
|
@@ -73,7 +107,7 @@ export class Server {}
|
|
|
73
107
|
|
|
74
108
|
## Create a new Service
|
|
75
109
|
|
|
76
|
-
Decorate the class with `@
|
|
110
|
+
Decorate the class with `@JobsController`. The `namespace` option is optional and will
|
|
77
111
|
prefix the job name with `namespace.`
|
|
78
112
|
|
|
79
113
|
Use the `@Every` decorator to define a cron-like job that gets automatically
|
|
@@ -83,6 +117,22 @@ method name is used as job name.
|
|
|
83
117
|
Use the `@Define` decorator on methods that you would like to schedule
|
|
84
118
|
programmatically via the AgendaService and Agenda instance access.
|
|
85
119
|
|
|
120
|
+
### Migration note for decorators and injection
|
|
121
|
+
|
|
122
|
+
```diff
|
|
123
|
+
-import {Agenda, AgendaModule, Define, Every} from "@tsed/agenda";
|
|
124
|
+
+import {Define, Every, JobsController} from "@tsed/agenda";
|
|
125
|
+
+import {Agenda} from "agenda";
|
|
126
|
+
|
|
127
|
+
-@Agenda({namespace: "email"})
|
|
128
|
+
+@JobsController({namespace: "email"})
|
|
129
|
+
export class EmailJobService {
|
|
130
|
+
@Inject()
|
|
131
|
+
- agenda: AgendaModule;
|
|
132
|
+
+ agenda: Agenda;
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
86
136
|
```ts
|
|
87
137
|
import {Every, Define, JobsController} from "@tsed/agenda";
|
|
88
138
|
import {Job} from "agenda";
|
|
@@ -114,8 +164,8 @@ export class EmailJobService {
|
|
|
114
164
|
|
|
115
165
|
## Define a job processor manually
|
|
116
166
|
|
|
117
|
-
|
|
118
|
-
|
|
167
|
+
Inject `Agenda` from `agenda` to manually define a job processor. It can be useful when you need to fetch data
|
|
168
|
+
beforehand and dynamically build job name / options.
|
|
119
169
|
|
|
120
170
|
```typescript
|
|
121
171
|
import {Define, JobsController} from "@tsed/agenda";
|
|
@@ -162,12 +212,11 @@ export class EmailJobService {
|
|
|
162
212
|
|
|
163
213
|
## Inject Agenda
|
|
164
214
|
|
|
165
|
-
Inject the
|
|
215
|
+
Inject the Agenda instance to interact with it directly, e.g. to schedule
|
|
166
216
|
a job manually.
|
|
167
217
|
|
|
168
218
|
```ts
|
|
169
219
|
import {Service} from "@tsed/di";
|
|
170
|
-
import {AfterRoutesInit} from "@tsed/platform-params";
|
|
171
220
|
import {Agenda} from "agenda";
|
|
172
221
|
|
|
173
222
|
@Service()
|
|
@@ -200,7 +249,7 @@ This is an optional feature and is not required to use agenda.
|
|
|
200
249
|
Install the additional dependency.
|
|
201
250
|
|
|
202
251
|
```shell
|
|
203
|
-
npm install --save agendash
|
|
252
|
+
npm install --save agendash agenda @agendajs/mongo-backend
|
|
204
253
|
```
|
|
205
254
|
|
|
206
255
|
Afterward create the module `agendash.module.ts` in src/modules so that the dashboard can be exposed using middleware.
|
|
@@ -209,7 +258,7 @@ Afterward create the module `agendash.module.ts` in src/modules so that the dash
|
|
|
209
258
|
import {AfterRoutesInit, PlatformApplication} from "@tsed/platform-http";
|
|
210
259
|
import {Configuration, Inject, Module} from "@tsed/di";
|
|
211
260
|
import {Agenda} from "agenda";
|
|
212
|
-
import
|
|
261
|
+
import {expressMiddleware} from "agendash";
|
|
213
262
|
|
|
214
263
|
@Module()
|
|
215
264
|
export class AgendashModule implements AfterRoutesInit {
|
|
@@ -224,7 +273,7 @@ export class AgendashModule implements AfterRoutesInit {
|
|
|
224
273
|
|
|
225
274
|
$afterRoutesInit() {
|
|
226
275
|
if (this.config.agenda?.enabled) {
|
|
227
|
-
this.app.use("/agendash",
|
|
276
|
+
this.app.use("/agendash", expressMiddleware(this.agenda));
|
|
228
277
|
}
|
|
229
278
|
}
|
|
230
279
|
}
|
|
@@ -249,7 +298,7 @@ website. [[Become a sponsor](https://opencollective.com/tsed#sponsor)]
|
|
|
249
298
|
|
|
250
299
|
The MIT License (MIT)
|
|
251
300
|
|
|
252
|
-
Copyright (c) 2016 -
|
|
301
|
+
Copyright (c) 2016 - Today Romain Lenzotti
|
|
253
302
|
|
|
254
303
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
|
255
304
|
documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|