@tsed/pulse 8.11.1 → 8.12.0-rc.1
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/constants/constants.js +0 -1
- package/lib/esm/decorators/define.js +0 -1
- package/lib/esm/decorators/every.js +0 -1
- package/lib/esm/decorators/pulse.js +5 -2
- package/lib/esm/index.js +1 -3
- package/lib/esm/interfaces/PulseStore.js +0 -1
- package/lib/esm/interfaces/interfaces.js +0 -1
- package/lib/esm/services/PulseService.js +121 -0
- package/lib/types/decorators/pulse.d.ts +5 -1
- package/lib/types/index.d.ts +1 -2
- package/lib/types/interfaces/interfaces.d.ts +6 -8
- package/lib/types/services/PulseService.d.ts +13 -0
- package/package.json +10 -7
- package/lib/esm/PulseModule.js +0 -132
- package/lib/esm/PulseModule.js.map +0 -1
- package/lib/esm/constants/constants.js.map +0 -1
- package/lib/esm/decorators/define.js.map +0 -1
- package/lib/esm/decorators/every.js.map +0 -1
- package/lib/esm/decorators/pulse.js.map +0 -1
- package/lib/esm/index.js.map +0 -1
- package/lib/esm/interfaces/PulseStore.js.map +0 -1
- package/lib/esm/interfaces/interfaces.js.map +0 -1
- package/lib/esm/services/PulseFactory.js +0 -13
- package/lib/esm/services/PulseFactory.js.map +0 -1
- package/lib/types/PulseModule.d.ts +0 -24
- package/lib/types/services/PulseFactory.d.ts +0 -3
- package/src/PulseModule.spec.ts +0 -221
- package/src/PulseModule.ts +0 -156
- package/src/constants/constants.ts +0 -1
- package/src/decorators/define.spec.ts +0 -49
- package/src/decorators/define.ts +0 -15
- package/src/decorators/every.spec.ts +0 -37
- package/src/decorators/every.ts +0 -15
- package/src/decorators/pulse.spec.ts +0 -22
- package/src/decorators/pulse.ts +0 -17
- package/src/index.ts +0 -11
- package/src/interfaces/PulseStore.ts +0 -13
- package/src/interfaces/interfaces.ts +0 -16
- package/src/services/PulseFactory.ts +0 -15
- package/vitest.config.mts +0 -25
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { StoreMerge, useDecorators } from "@tsed/core";
|
|
2
2
|
import { Injectable } from "@tsed/di";
|
|
3
3
|
import { PROVIDER_TYPE_PULSE } from "../constants/constants.js";
|
|
4
|
-
export function
|
|
4
|
+
export function JobsController(options) {
|
|
5
5
|
return useDecorators(options?.namespace && StoreMerge("pulse", options), Injectable({
|
|
6
6
|
type: PROVIDER_TYPE_PULSE
|
|
7
7
|
}));
|
|
8
8
|
}
|
|
9
|
-
|
|
9
|
+
/**
|
|
10
|
+
* @deprecated Use `JobsController` instead.
|
|
11
|
+
*/
|
|
12
|
+
export const Pulse = JobsController;
|
package/lib/esm/index.js
CHANGED
|
@@ -7,6 +7,4 @@ export * from "./decorators/every.js";
|
|
|
7
7
|
export * from "./decorators/pulse.js";
|
|
8
8
|
export * from "./interfaces/interfaces.js";
|
|
9
9
|
export * from "./interfaces/PulseStore.js";
|
|
10
|
-
export * from "./
|
|
11
|
-
export * from "./services/PulseFactory.js";
|
|
12
|
-
//# sourceMappingURL=index.js.map
|
|
10
|
+
export * from "./services/PulseService.js";
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { Pulse } from "@pulsecron/pulse";
|
|
2
|
+
import { constant, DIContext, injectable, injector, logger, runInContext } from "@tsed/di";
|
|
3
|
+
import { $asyncEmit } from "@tsed/hooks";
|
|
4
|
+
import { v4 as uuid } from "uuid";
|
|
5
|
+
import { PROVIDER_TYPE_PULSE } from "../constants/constants.js";
|
|
6
|
+
function getOpts() {
|
|
7
|
+
return constant("pulse", { enabled: false });
|
|
8
|
+
}
|
|
9
|
+
function addPulseDefinitionsForProvider(pulse, provider) {
|
|
10
|
+
const store = provider.store.get("pulse", {});
|
|
11
|
+
if (!store.define) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
Object.entries(store.define).forEach(([propertyKey, { name, ...options }]) => {
|
|
15
|
+
const instance = injector().get(provider.token);
|
|
16
|
+
const jobProcessor = instance[propertyKey].bind(instance);
|
|
17
|
+
const jobName = getNameForJob(propertyKey, store.namespace, name);
|
|
18
|
+
pulse.define(jobName, jobProcessor, options);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
async function scheduleJobsForProvider(pulse, provider) {
|
|
22
|
+
const store = provider.store.get("pulse", {});
|
|
23
|
+
if (!store.every) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const promises = Object.entries(store.every).map(([propertyKey, { interval, name, ...options }]) => {
|
|
27
|
+
const jobName = getNameForJob(propertyKey, store.namespace, name);
|
|
28
|
+
return pulse.every(interval, jobName, {}, options);
|
|
29
|
+
});
|
|
30
|
+
await Promise.all(promises);
|
|
31
|
+
}
|
|
32
|
+
function getNameForJob(propertyKey, namespace, customName) {
|
|
33
|
+
const name = customName || propertyKey;
|
|
34
|
+
return namespace ? `${namespace}.${name}` : name;
|
|
35
|
+
}
|
|
36
|
+
async function afterListen(pulse) {
|
|
37
|
+
const opts = getOpts();
|
|
38
|
+
if (opts.enabled) {
|
|
39
|
+
const providers = injector().getProviders(PROVIDER_TYPE_PULSE);
|
|
40
|
+
if (!opts.disableJobProcessing) {
|
|
41
|
+
logger().info({
|
|
42
|
+
event: "PULSE_ADD_DEFINITIONS",
|
|
43
|
+
message: "Pulse add definitions"
|
|
44
|
+
});
|
|
45
|
+
providers.forEach((provider) => addPulseDefinitionsForProvider(pulse, provider));
|
|
46
|
+
await $asyncEmit("$beforePulseStart");
|
|
47
|
+
}
|
|
48
|
+
await pulse.start();
|
|
49
|
+
if (!opts.disableJobProcessing) {
|
|
50
|
+
logger().info({
|
|
51
|
+
event: "PULSE_ADD_JOBS",
|
|
52
|
+
message: "Pulse add scheduled jobs"
|
|
53
|
+
});
|
|
54
|
+
await Promise.all(providers.map((provider) => scheduleJobsForProvider(pulse, provider)));
|
|
55
|
+
await $asyncEmit("$afterPulseStart");
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async function onDestroy(pulse) {
|
|
60
|
+
const opts = getOpts();
|
|
61
|
+
if (opts.enabled) {
|
|
62
|
+
if (opts.drainJobsBeforeClose && "drain" in pulse) {
|
|
63
|
+
logger().info({
|
|
64
|
+
event: "PULSE_DRAIN",
|
|
65
|
+
message: "Pulse is draining all jobs before close"
|
|
66
|
+
});
|
|
67
|
+
await pulse.drain();
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
logger().info({
|
|
71
|
+
event: "PULSE_STOP",
|
|
72
|
+
message: "Pulse is stopping"
|
|
73
|
+
});
|
|
74
|
+
await pulse.stop();
|
|
75
|
+
}
|
|
76
|
+
await pulse.close({ force: true });
|
|
77
|
+
logger().info({ event: "PULSE_STOP", message: "Pulse stopped" });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
export const PulseService = injectable(Pulse)
|
|
81
|
+
.factory(() => {
|
|
82
|
+
const opts = getOpts();
|
|
83
|
+
if (opts.enabled) {
|
|
84
|
+
const pulse = new Pulse(opts);
|
|
85
|
+
return new Proxy(pulse, {
|
|
86
|
+
set(target, prop, value) {
|
|
87
|
+
return Reflect.set(target, prop, value);
|
|
88
|
+
},
|
|
89
|
+
get(target, prop) {
|
|
90
|
+
if (prop === "pulse") {
|
|
91
|
+
return target;
|
|
92
|
+
}
|
|
93
|
+
if (prop === "$define") {
|
|
94
|
+
return Reflect.get(target, "define", target);
|
|
95
|
+
}
|
|
96
|
+
if (prop === "define") {
|
|
97
|
+
return (name, processor, options) => {
|
|
98
|
+
return target["define"](name, (job) => {
|
|
99
|
+
const $ctx = new DIContext({
|
|
100
|
+
id: uuid()
|
|
101
|
+
});
|
|
102
|
+
$ctx.set("job", job);
|
|
103
|
+
return runInContext($ctx, () => processor(job));
|
|
104
|
+
}, options);
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
return Reflect.get(target, prop, target);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
return new Proxy({}, { get: () => () => Promise.resolve() });
|
|
112
|
+
})
|
|
113
|
+
.hooks({
|
|
114
|
+
$afterListen: afterListen,
|
|
115
|
+
$onDestroy: onDestroy
|
|
116
|
+
})
|
|
117
|
+
.token();
|
|
118
|
+
/**
|
|
119
|
+
* @deprecated Use `Pulse` from `pulse` instead.
|
|
120
|
+
*/
|
|
121
|
+
export const PulseModule = Pulse;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
interface PulseOptions {
|
|
2
2
|
namespace?: string;
|
|
3
3
|
}
|
|
4
|
-
export declare function
|
|
4
|
+
export declare function JobsController(options?: PulseOptions): ClassDecorator;
|
|
5
|
+
/**
|
|
6
|
+
* @deprecated Use `JobsController` instead.
|
|
7
|
+
*/
|
|
8
|
+
export declare const Pulse: typeof JobsController;
|
|
5
9
|
export {};
|
package/lib/types/index.d.ts
CHANGED
|
@@ -7,5 +7,4 @@ export * from "./decorators/every.js";
|
|
|
7
7
|
export * from "./decorators/pulse.js";
|
|
8
8
|
export * from "./interfaces/interfaces.js";
|
|
9
9
|
export * from "./interfaces/PulseStore.js";
|
|
10
|
-
export * from "./
|
|
11
|
-
export * from "./services/PulseFactory.js";
|
|
10
|
+
export * from "./services/PulseService.js";
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import { PulseConfig } from "@pulsecron/pulse";
|
|
2
|
+
export type PulseSettings = PulseConfig & {
|
|
3
|
+
enabled?: boolean;
|
|
4
|
+
disableJobProcessing?: boolean;
|
|
5
|
+
drainJobsBeforeClose?: boolean;
|
|
6
|
+
};
|
|
2
7
|
declare global {
|
|
3
8
|
namespace TsED {
|
|
4
9
|
interface Configuration {
|
|
5
|
-
pulse?:
|
|
6
|
-
/**
|
|
7
|
-
* Enable Pulse jobs. Default false.
|
|
8
|
-
*/
|
|
9
|
-
enabled?: boolean;
|
|
10
|
-
disableJobProcessing?: boolean;
|
|
11
|
-
drainJobsBeforeClose?: boolean;
|
|
12
|
-
} & PulseConfig;
|
|
10
|
+
pulse?: PulseSettings;
|
|
13
11
|
}
|
|
14
12
|
}
|
|
15
13
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Pulse } from "@pulsecron/pulse";
|
|
2
|
+
export declare const PulseService: {
|
|
3
|
+
readonly __type: "token_factory";
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* @deprecated Use `Pulse` from `pulse` instead.
|
|
7
|
+
*/
|
|
8
|
+
export type PulseService = Pulse;
|
|
9
|
+
/**
|
|
10
|
+
* @deprecated Use `Pulse` from `pulse` instead.
|
|
11
|
+
*/
|
|
12
|
+
export declare const PulseModule: typeof Pulse;
|
|
13
|
+
export type PulseModule = Pulse;
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@tsed/pulse",
|
|
3
3
|
"description": "@pulsecron/pulse package for Ts.ED framework",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "8.
|
|
5
|
+
"version": "8.12.0-rc.1",
|
|
6
6
|
"source": "./src/index.ts",
|
|
7
7
|
"main": "./lib/esm/index.js",
|
|
8
8
|
"module": "./lib/esm/index.js",
|
|
@@ -27,11 +27,11 @@
|
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@pulsecron/pulse": "^1.6.3",
|
|
30
|
-
"@tsed/barrels": "8.
|
|
31
|
-
"@tsed/core": "8.
|
|
32
|
-
"@tsed/di": "8.
|
|
33
|
-
"@tsed/platform-http": "8.
|
|
34
|
-
"@tsed/typescript": "8.
|
|
30
|
+
"@tsed/barrels": "8.12.0-rc.1",
|
|
31
|
+
"@tsed/core": "8.12.0-rc.1",
|
|
32
|
+
"@tsed/di": "8.12.0-rc.1",
|
|
33
|
+
"@tsed/platform-http": "8.12.0-rc.1",
|
|
34
|
+
"@tsed/typescript": "8.12.0-rc.1",
|
|
35
35
|
"eslint": "9.12.0",
|
|
36
36
|
"typescript": "5.4.5",
|
|
37
37
|
"vitest": "3.1.4"
|
|
@@ -45,5 +45,8 @@
|
|
|
45
45
|
},
|
|
46
46
|
"homepage": "https://github.com/tsedio/tsed/tree/production/packages/third-parties/pulse",
|
|
47
47
|
"author": "Romain Lenzotti",
|
|
48
|
-
"license": "MIT"
|
|
48
|
+
"license": "MIT",
|
|
49
|
+
"publishConfig": {
|
|
50
|
+
"tag": "rc"
|
|
51
|
+
}
|
|
49
52
|
}
|
package/lib/esm/PulseModule.js
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import { __decorate, __metadata } from "tslib";
|
|
2
|
-
import { Constant, DIContext, Inject, InjectorService, Module, runInContext } from "@tsed/di";
|
|
3
|
-
import { Logger } from "@tsed/logger";
|
|
4
|
-
import { v4 as uuid } from "uuid";
|
|
5
|
-
import { PROVIDER_TYPE_PULSE } from "./constants/constants.js";
|
|
6
|
-
import { PulseService } from "./services/PulseFactory.js";
|
|
7
|
-
let PulseModule = class PulseModule {
|
|
8
|
-
async $afterListen() {
|
|
9
|
-
if (this.enabled) {
|
|
10
|
-
const providers = this.getProviders();
|
|
11
|
-
if (!this.disableJobProcessing) {
|
|
12
|
-
this.logger.info({
|
|
13
|
-
event: "PULSE_ADD_DEFINITIONS",
|
|
14
|
-
message: "Pulse add definitions"
|
|
15
|
-
});
|
|
16
|
-
providers.forEach((provider) => this.addPulseDefinitionsForProvider(provider));
|
|
17
|
-
await this.injector.emit("$beforePulseStart");
|
|
18
|
-
}
|
|
19
|
-
await this.pulse.start();
|
|
20
|
-
if (!this.disableJobProcessing) {
|
|
21
|
-
this.logger.info({
|
|
22
|
-
event: "PULSE_ADD_JOBS",
|
|
23
|
-
message: "Pulse add scheduled jobs"
|
|
24
|
-
});
|
|
25
|
-
await Promise.all(providers.map((provider) => this.scheduleJobsForProvider(provider)));
|
|
26
|
-
await this.injector.emit("$afterPulseStart");
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
async $onDestroy() {
|
|
31
|
-
if (this.enabled) {
|
|
32
|
-
if (this.drainJobsBeforeClose && "drain" in this.pulse) {
|
|
33
|
-
this.logger.info({
|
|
34
|
-
event: "PULSE_DRAIN",
|
|
35
|
-
message: "Pulse is draining all jobs before close"
|
|
36
|
-
});
|
|
37
|
-
await this.pulse.drain();
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
this.logger.info({
|
|
41
|
-
event: "PULSE_STOP",
|
|
42
|
-
message: "Pulse is stopping"
|
|
43
|
-
});
|
|
44
|
-
await this.pulse.stop();
|
|
45
|
-
}
|
|
46
|
-
await this.pulse.close({ force: true });
|
|
47
|
-
this.logger.info({ event: "PULSE_STOP", message: "Pulse stopped" });
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
define(name, processor, options) {
|
|
51
|
-
return this.pulse.define(name, (job, ...rest) => {
|
|
52
|
-
const $ctx = new DIContext({
|
|
53
|
-
injector: this.injector,
|
|
54
|
-
id: uuid(),
|
|
55
|
-
logger: this.injector.logger
|
|
56
|
-
});
|
|
57
|
-
$ctx.set("job", job);
|
|
58
|
-
return runInContext($ctx, () => processor(job, ...rest));
|
|
59
|
-
}, options);
|
|
60
|
-
}
|
|
61
|
-
every(interval, name, data, options) {
|
|
62
|
-
return this.pulse.every(interval, name, data, options);
|
|
63
|
-
}
|
|
64
|
-
schedule(when, name, data) {
|
|
65
|
-
return this.pulse.schedule(when, name, data);
|
|
66
|
-
}
|
|
67
|
-
now(name, data) {
|
|
68
|
-
return this.pulse.now(name, data);
|
|
69
|
-
}
|
|
70
|
-
create(name, data) {
|
|
71
|
-
return this.pulse.create(name, data);
|
|
72
|
-
}
|
|
73
|
-
getProviders() {
|
|
74
|
-
return this.injector.getProviders(PROVIDER_TYPE_PULSE);
|
|
75
|
-
}
|
|
76
|
-
addPulseDefinitionsForProvider(provider) {
|
|
77
|
-
const store = provider.store.get("pulse", {});
|
|
78
|
-
if (!store.define) {
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
Object.entries(store.define).forEach(([propertyKey, { name, ...options }]) => {
|
|
82
|
-
const instance = this.injector.get(provider.token);
|
|
83
|
-
const jobProcessor = instance[propertyKey].bind(instance);
|
|
84
|
-
const jobName = this.getNameForJob(propertyKey, store.namespace, name);
|
|
85
|
-
this.define(jobName, jobProcessor, options);
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
async scheduleJobsForProvider(provider) {
|
|
89
|
-
const store = provider.store.get("pulse", {});
|
|
90
|
-
if (!store.every) {
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
const promises = Object.entries(store.every).map(([propertyKey, { interval, name, ...options }]) => {
|
|
94
|
-
const jobName = this.getNameForJob(propertyKey, store.namespace, name);
|
|
95
|
-
return this.every(interval, jobName, {}, options);
|
|
96
|
-
});
|
|
97
|
-
await Promise.all(promises);
|
|
98
|
-
}
|
|
99
|
-
getNameForJob(propertyKey, namespace, customName) {
|
|
100
|
-
const name = customName || propertyKey;
|
|
101
|
-
return namespace ? `${namespace}.${name}` : name;
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
__decorate([
|
|
105
|
-
Inject(),
|
|
106
|
-
__metadata("design:type", Logger)
|
|
107
|
-
], PulseModule.prototype, "logger", void 0);
|
|
108
|
-
__decorate([
|
|
109
|
-
Inject(),
|
|
110
|
-
__metadata("design:type", InjectorService)
|
|
111
|
-
], PulseModule.prototype, "injector", void 0);
|
|
112
|
-
__decorate([
|
|
113
|
-
Inject(),
|
|
114
|
-
__metadata("design:type", PulseService)
|
|
115
|
-
], PulseModule.prototype, "pulse", void 0);
|
|
116
|
-
__decorate([
|
|
117
|
-
Constant("pulse.enabled", false),
|
|
118
|
-
__metadata("design:type", Boolean)
|
|
119
|
-
], PulseModule.prototype, "enabled", void 0);
|
|
120
|
-
__decorate([
|
|
121
|
-
Constant("pulse.drainJobsBeforeClose", false),
|
|
122
|
-
__metadata("design:type", Boolean)
|
|
123
|
-
], PulseModule.prototype, "drainJobsBeforeClose", void 0);
|
|
124
|
-
__decorate([
|
|
125
|
-
Constant("pulse.disableJobProcessing", false),
|
|
126
|
-
__metadata("design:type", Boolean)
|
|
127
|
-
], PulseModule.prototype, "disableJobProcessing", void 0);
|
|
128
|
-
PulseModule = __decorate([
|
|
129
|
-
Module()
|
|
130
|
-
], PulseModule);
|
|
131
|
-
export { PulseModule };
|
|
132
|
-
//# sourceMappingURL=PulseModule.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PulseModule.js","sourceRoot":"","sources":["../../src/PulseModule.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/constants/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG,qBAAqB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"define.js","sourceRoot":"","sources":["../../../src/decorators/define.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAC,MAAM,YAAY,CAAC;AAIjC,MAAM,UAAU,MAAM,CAAC,UAAyB,EAAE;IAChD,OAAO,CAAC,MAAW,EAAE,WAAmB,EAAE,EAAE;QAC1C,MAAM,KAAK,GAAe;YACxB,MAAM,EAAE;gBACN,CAAC,WAAW,CAAC,EAAE,OAAO;aACvB;SACF,CAAC;QAEF,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC3C,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"every.js","sourceRoot":"","sources":["../../../src/decorators/every.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAE,aAAa,EAAC,MAAM,YAAY,CAAC;AAGhD,OAAO,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AAEnC,MAAM,UAAU,KAAK,CAAC,QAAgB,EAAE,UAAwB,EAAE;IAChE,OAAO,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,MAAW,EAAE,WAAmB,EAAE,EAAE;QACzE,MAAM,KAAK,GAAe;YACxB,KAAK,EAAE;gBACL,CAAC,WAAW,CAAC,EAAE,EAAC,GAAG,OAAO,EAAE,QAAQ,EAAC;aACtC;SACF,CAAC;QACF,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pulse.js","sourceRoot":"","sources":["../../../src/decorators/pulse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,aAAa,EAAC,MAAM,YAAY,CAAC;AACrD,OAAO,EAAC,UAAU,EAAC,MAAM,UAAU,CAAC;AAEpC,OAAO,EAAC,mBAAmB,EAAC,MAAM,2BAA2B,CAAC;AAM9D,MAAM,UAAU,KAAK,CAAC,OAAsB;IAC1C,OAAO,aAAa,CAClB,OAAO,EAAE,SAAS,IAAI,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,EAClD,UAAU,CAAC;QACT,IAAI,EAAE,mBAAmB;KAC1B,CAAC,CACH,CAAC;AACJ,CAAC"}
|
package/lib/esm/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PulseStore.js","sourceRoot":"","sources":["../../../src/interfaces/PulseStore.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../../../src/interfaces/interfaces.ts"],"names":[],"mappings":""}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { Pulse } from "@pulsecron/pulse";
|
|
2
|
-
import { Configuration, registerProvider } from "@tsed/di";
|
|
3
|
-
// create Alias to avoid confusing import between Pulse from "@pulsecron/pulse" and Pulse decorator
|
|
4
|
-
export const PulseService = Pulse;
|
|
5
|
-
registerProvider({
|
|
6
|
-
token: Pulse,
|
|
7
|
-
deps: [Configuration],
|
|
8
|
-
useFactory(settings) {
|
|
9
|
-
const opts = settings.get("pulse", { enabled: false });
|
|
10
|
-
return opts.enabled ? new Pulse(opts) : {};
|
|
11
|
-
}
|
|
12
|
-
});
|
|
13
|
-
//# sourceMappingURL=PulseFactory.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PulseFactory.js","sourceRoot":"","sources":["../../../src/services/PulseFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,KAAK,EAAc,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAC,aAAa,EAAE,gBAAgB,EAAC,MAAM,UAAU,CAAC;AAEzD,mGAAmG;AACnG,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,CAAC;AAGlC,gBAAgB,CAAC;IACf,KAAK,EAAE,KAAK;IACZ,IAAI,EAAE,CAAC,aAAa,CAAC;IACrB,UAAU,CAAC,QAAuB;QAChC,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAmC,OAAO,EAAE,EAAC,OAAO,EAAE,KAAK,EAAC,CAAC,CAAC;QACvF,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7C,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { DefineOptions, Job, JobAttributesData, Processor } from "@pulsecron/pulse";
|
|
2
|
-
import { InjectorService, OnDestroy, Provider } from "@tsed/di";
|
|
3
|
-
import { Logger } from "@tsed/logger";
|
|
4
|
-
import { AfterListen } from "@tsed/platform-http";
|
|
5
|
-
import { PulseService } from "./services/PulseFactory.js";
|
|
6
|
-
export declare class PulseModule implements OnDestroy, AfterListen {
|
|
7
|
-
protected logger: Logger;
|
|
8
|
-
protected injector: InjectorService;
|
|
9
|
-
protected pulse: PulseService;
|
|
10
|
-
private enabled;
|
|
11
|
-
private drainJobsBeforeClose;
|
|
12
|
-
private disableJobProcessing;
|
|
13
|
-
$afterListen(): Promise<any>;
|
|
14
|
-
$onDestroy(): Promise<any>;
|
|
15
|
-
define<T extends JobAttributesData>(name: string, processor: Processor<T>, options?: DefineOptions): void;
|
|
16
|
-
every(interval: string, name: string, data?: any, options?: any): Promise<Job<JobAttributesData> | Job<JobAttributesData>[]>;
|
|
17
|
-
schedule(when: Date | string, name: string, data?: any): Promise<Job<{}>[]> | Promise<Job<any>>;
|
|
18
|
-
now(name: string, data?: any): Promise<Job<JobAttributesData>>;
|
|
19
|
-
create(name: string, data?: any): Job<any>;
|
|
20
|
-
protected getProviders(): Provider<any>[];
|
|
21
|
-
protected addPulseDefinitionsForProvider(provider: Provider): void;
|
|
22
|
-
protected scheduleJobsForProvider(provider: Provider<any>): Promise<void>;
|
|
23
|
-
protected getNameForJob(propertyKey: string, namespace?: string, customName?: string): string;
|
|
24
|
-
}
|
package/src/PulseModule.spec.ts
DELETED
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
import type {Job} from "@pulsecron/pulse";
|
|
2
|
-
import {Inject} from "@tsed/di";
|
|
3
|
-
import {PlatformTest} from "@tsed/platform-http/testing";
|
|
4
|
-
|
|
5
|
-
import {Define} from "./decorators/define.js";
|
|
6
|
-
import {Every} from "./decorators/every.js";
|
|
7
|
-
import {Pulse} from "./decorators/pulse.js";
|
|
8
|
-
import {PulseModule} from "./PulseModule.js";
|
|
9
|
-
|
|
10
|
-
vi.mock("@pulsecron/pulse", () => {
|
|
11
|
-
return {
|
|
12
|
-
Pulse: class {
|
|
13
|
-
close = vi.fn();
|
|
14
|
-
stop = vi.fn();
|
|
15
|
-
drain = vi.fn();
|
|
16
|
-
define = vi.fn();
|
|
17
|
-
every = vi.fn();
|
|
18
|
-
schedule = vi.fn();
|
|
19
|
-
now = vi.fn();
|
|
20
|
-
create = vi.fn().mockReturnValue({
|
|
21
|
-
repeatEvery: vi.fn().mockReturnThis(),
|
|
22
|
-
save: vi.fn()
|
|
23
|
-
});
|
|
24
|
-
start = vi.fn();
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
@Pulse({namespace: "test-nsp"})
|
|
30
|
-
class CustomCampaign {
|
|
31
|
-
@Inject()
|
|
32
|
-
pulse: PulseModule;
|
|
33
|
-
|
|
34
|
-
job: Job;
|
|
35
|
-
|
|
36
|
-
$beforePulseStart() {
|
|
37
|
-
this.job = this.pulse.create("customName2", {
|
|
38
|
-
locale: "fr-FR"
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
$afterPulseStart() {
|
|
43
|
-
return this.job.repeatEvery("1 week").save();
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
@Every("60 seconds")
|
|
47
|
-
test(job: Job) {
|
|
48
|
-
// test
|
|
49
|
-
return "hello " + job.attrs.name;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
@Define({name: "customName"})
|
|
53
|
-
test2(job: Job) {
|
|
54
|
-
// test
|
|
55
|
-
return "hello " + job.attrs.name;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
@Define({name: "customName2"})
|
|
59
|
-
test3() {
|
|
60
|
-
// test
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
@Pulse({namespace: "test-nsp-2"})
|
|
65
|
-
class CustomCampaign2 {
|
|
66
|
-
@Define({name: "customName"})
|
|
67
|
-
test(job: Job) {
|
|
68
|
-
// test
|
|
69
|
-
return "hello " + job.attrs.name;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
@Pulse({namespace: "test-nsp-3"})
|
|
74
|
-
class CustomCampaign3 {}
|
|
75
|
-
|
|
76
|
-
describe("PulseModule", () => {
|
|
77
|
-
describe("when pulse is enabled", () => {
|
|
78
|
-
beforeEach(() =>
|
|
79
|
-
PlatformTest.create({
|
|
80
|
-
pulse: {
|
|
81
|
-
enabled: true
|
|
82
|
-
}
|
|
83
|
-
})
|
|
84
|
-
);
|
|
85
|
-
afterEach(() => PlatformTest.reset());
|
|
86
|
-
|
|
87
|
-
describe("$afterListen()", () => {
|
|
88
|
-
it("should load all jobs", async () => {
|
|
89
|
-
const pulseModule = PlatformTest.get<any>(PulseModule)!;
|
|
90
|
-
const campaign = PlatformTest.get<CustomCampaign>(CustomCampaign)!;
|
|
91
|
-
|
|
92
|
-
await pulseModule.$afterListen();
|
|
93
|
-
|
|
94
|
-
expect(pulseModule.pulse.define).toHaveBeenCalledWith("test-nsp.test", expect.any(Function), {});
|
|
95
|
-
expect(pulseModule.pulse.every).toHaveBeenCalledWith("60 seconds", "test-nsp.test", {}, {});
|
|
96
|
-
expect(pulseModule.pulse.start).toHaveBeenCalledWith();
|
|
97
|
-
expect(pulseModule.pulse.create).toHaveBeenCalledWith("customName2", {locale: "fr-FR"});
|
|
98
|
-
|
|
99
|
-
expect(campaign.job.repeatEvery).toHaveBeenCalledWith("1 week");
|
|
100
|
-
expect(campaign.job.save).toHaveBeenCalledWith();
|
|
101
|
-
|
|
102
|
-
const result = await pulseModule.pulse.define.mock.calls[0][1]({
|
|
103
|
-
attrs: {
|
|
104
|
-
name: "test-nsp.test"
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
expect(result).toEqual("hello test-nsp.test");
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
describe("schedule()", () => {
|
|
112
|
-
it("should schedule a job", async () => {
|
|
113
|
-
const pulseModule = PlatformTest.get<any>(PulseModule)!;
|
|
114
|
-
|
|
115
|
-
await pulseModule.schedule("now", "test-nsp.test", {});
|
|
116
|
-
|
|
117
|
-
expect(pulseModule.pulse.schedule).toHaveBeenCalledWith("now", "test-nsp.test", {});
|
|
118
|
-
});
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
describe("now()", () => {
|
|
122
|
-
it("should schedule a job", async () => {
|
|
123
|
-
const pulseModule = PlatformTest.get<any>(PulseModule)!;
|
|
124
|
-
|
|
125
|
-
await pulseModule.now("test-nsp.test", {});
|
|
126
|
-
|
|
127
|
-
expect(pulseModule.pulse.now).toHaveBeenCalledWith("test-nsp.test", {});
|
|
128
|
-
});
|
|
129
|
-
});
|
|
130
|
-
describe("$onDestroy()", () => {
|
|
131
|
-
it("should close pulse", async () => {
|
|
132
|
-
const pulseModule = PlatformTest.get<any>(PulseModule)!;
|
|
133
|
-
|
|
134
|
-
await pulseModule.$onDestroy();
|
|
135
|
-
|
|
136
|
-
expect(pulseModule.pulse.stop).toHaveBeenCalledWith();
|
|
137
|
-
expect(pulseModule.pulse.close).toHaveBeenCalledWith({force: true});
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
});
|
|
141
|
-
describe("when pulse is enabled and drainJobsBeforeClose = true", () => {
|
|
142
|
-
beforeEach(() =>
|
|
143
|
-
PlatformTest.create({
|
|
144
|
-
pulse: {
|
|
145
|
-
enabled: true,
|
|
146
|
-
drainJobsBeforeClose: true
|
|
147
|
-
}
|
|
148
|
-
})
|
|
149
|
-
);
|
|
150
|
-
afterEach(() => PlatformTest.reset());
|
|
151
|
-
describe("$onDestroy()", () => {
|
|
152
|
-
it("should close pulse", async () => {
|
|
153
|
-
const pulseModule = PlatformTest.get<any>(PulseModule)!;
|
|
154
|
-
|
|
155
|
-
await pulseModule.$onDestroy();
|
|
156
|
-
|
|
157
|
-
expect(pulseModule.pulse.drain).toHaveBeenCalledWith();
|
|
158
|
-
expect(pulseModule.pulse.close).toHaveBeenCalledWith({force: true});
|
|
159
|
-
});
|
|
160
|
-
});
|
|
161
|
-
});
|
|
162
|
-
describe("when pulse is enabled but disableJobProcessing = true", () => {
|
|
163
|
-
beforeEach(() =>
|
|
164
|
-
PlatformTest.create({
|
|
165
|
-
pulse: {
|
|
166
|
-
enabled: true,
|
|
167
|
-
disableJobProcessing: true
|
|
168
|
-
}
|
|
169
|
-
})
|
|
170
|
-
);
|
|
171
|
-
afterEach(() => PlatformTest.reset());
|
|
172
|
-
|
|
173
|
-
describe("$afterListen()", () => {
|
|
174
|
-
it("should load all jobs", async () => {
|
|
175
|
-
const pulseModule = PlatformTest.get<any>(PulseModule)!;
|
|
176
|
-
const campaign = PlatformTest.get<CustomCampaign>(CustomCampaign)!;
|
|
177
|
-
|
|
178
|
-
await pulseModule.$afterListen();
|
|
179
|
-
|
|
180
|
-
expect(pulseModule.pulse.define).not.toHaveBeenCalled();
|
|
181
|
-
expect(pulseModule.pulse.every).not.toHaveBeenCalled();
|
|
182
|
-
expect(pulseModule.pulse.start).toHaveBeenCalledWith();
|
|
183
|
-
expect(pulseModule.pulse.create).not.toHaveBeenCalled();
|
|
184
|
-
|
|
185
|
-
expect(campaign.job).toBeUndefined();
|
|
186
|
-
});
|
|
187
|
-
});
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
describe("when pulse is disabled", () => {
|
|
191
|
-
beforeEach(() =>
|
|
192
|
-
PlatformTest.create({
|
|
193
|
-
pulse: {
|
|
194
|
-
enabled: false
|
|
195
|
-
}
|
|
196
|
-
})
|
|
197
|
-
);
|
|
198
|
-
afterEach(() => PlatformTest.reset());
|
|
199
|
-
|
|
200
|
-
describe("$afterListen()", () => {
|
|
201
|
-
it("should load all jobs", async () => {
|
|
202
|
-
const pulseModule = PlatformTest.get<any>(PulseModule)!;
|
|
203
|
-
const campaign = PlatformTest.get<CustomCampaign>(CustomCampaign)!;
|
|
204
|
-
|
|
205
|
-
await pulseModule.$afterListen();
|
|
206
|
-
|
|
207
|
-
expect(pulseModule.pulse.define).toBeUndefined();
|
|
208
|
-
|
|
209
|
-
expect(campaign.job).toBeUndefined();
|
|
210
|
-
});
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
describe("$onDestroy()", () => {
|
|
214
|
-
it("should do nothing", async () => {
|
|
215
|
-
const pulseModule = PlatformTest.get<any>(PulseModule)!;
|
|
216
|
-
|
|
217
|
-
await pulseModule.$onDestroy();
|
|
218
|
-
});
|
|
219
|
-
});
|
|
220
|
-
});
|
|
221
|
-
});
|
package/src/PulseModule.ts
DELETED
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
import {DefineOptions, Job, JobAttributesData, Processor} from "@pulsecron/pulse";
|
|
2
|
-
import {Constant, DIContext, Inject, InjectorService, Module, OnDestroy, Provider, runInContext} from "@tsed/di";
|
|
3
|
-
import {Logger} from "@tsed/logger";
|
|
4
|
-
import {AfterListen} from "@tsed/platform-http";
|
|
5
|
-
import {v4 as uuid} from "uuid";
|
|
6
|
-
|
|
7
|
-
import {PROVIDER_TYPE_PULSE} from "./constants/constants.js";
|
|
8
|
-
import {PulseStore} from "./interfaces/PulseStore.js";
|
|
9
|
-
import {PulseService} from "./services/PulseFactory.js";
|
|
10
|
-
|
|
11
|
-
@Module()
|
|
12
|
-
export class PulseModule implements OnDestroy, AfterListen {
|
|
13
|
-
@Inject()
|
|
14
|
-
protected logger: Logger;
|
|
15
|
-
|
|
16
|
-
@Inject()
|
|
17
|
-
protected injector: InjectorService;
|
|
18
|
-
|
|
19
|
-
@Inject()
|
|
20
|
-
protected pulse: PulseService;
|
|
21
|
-
|
|
22
|
-
@Constant("pulse.enabled", false)
|
|
23
|
-
private enabled: boolean;
|
|
24
|
-
|
|
25
|
-
@Constant("pulse.drainJobsBeforeClose", false)
|
|
26
|
-
private drainJobsBeforeClose: boolean;
|
|
27
|
-
|
|
28
|
-
@Constant("pulse.disableJobProcessing", false)
|
|
29
|
-
private disableJobProcessing: boolean;
|
|
30
|
-
|
|
31
|
-
async $afterListen(): Promise<any> {
|
|
32
|
-
if (this.enabled) {
|
|
33
|
-
const providers = this.getProviders();
|
|
34
|
-
|
|
35
|
-
if (!this.disableJobProcessing) {
|
|
36
|
-
this.logger.info({
|
|
37
|
-
event: "PULSE_ADD_DEFINITIONS",
|
|
38
|
-
message: "Pulse add definitions"
|
|
39
|
-
});
|
|
40
|
-
providers.forEach((provider) => this.addPulseDefinitionsForProvider(provider));
|
|
41
|
-
|
|
42
|
-
await this.injector.emit("$beforePulseStart");
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
await this.pulse.start();
|
|
46
|
-
|
|
47
|
-
if (!this.disableJobProcessing) {
|
|
48
|
-
this.logger.info({
|
|
49
|
-
event: "PULSE_ADD_JOBS",
|
|
50
|
-
message: "Pulse add scheduled jobs"
|
|
51
|
-
});
|
|
52
|
-
await Promise.all(providers.map((provider) => this.scheduleJobsForProvider(provider)));
|
|
53
|
-
|
|
54
|
-
await this.injector.emit("$afterPulseStart");
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
async $onDestroy(): Promise<any> {
|
|
60
|
-
if (this.enabled) {
|
|
61
|
-
if (this.drainJobsBeforeClose && "drain" in this.pulse) {
|
|
62
|
-
this.logger.info({
|
|
63
|
-
event: "PULSE_DRAIN",
|
|
64
|
-
message: "Pulse is draining all jobs before close"
|
|
65
|
-
});
|
|
66
|
-
await this.pulse.drain();
|
|
67
|
-
} else {
|
|
68
|
-
this.logger.info({
|
|
69
|
-
event: "PULSE_STOP",
|
|
70
|
-
message: "Pulse is stopping"
|
|
71
|
-
});
|
|
72
|
-
await this.pulse.stop();
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
await this.pulse.close({force: true});
|
|
76
|
-
|
|
77
|
-
this.logger.info({event: "PULSE_STOP", message: "Pulse stopped"});
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
define<T extends JobAttributesData>(name: string, processor: Processor<T>, options?: DefineOptions) {
|
|
82
|
-
return this.pulse.define(
|
|
83
|
-
name,
|
|
84
|
-
(job: Job<T>, ...rest) => {
|
|
85
|
-
const $ctx = new DIContext({
|
|
86
|
-
injector: this.injector,
|
|
87
|
-
id: uuid(),
|
|
88
|
-
logger: this.injector.logger
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
$ctx.set("job", job);
|
|
92
|
-
|
|
93
|
-
return runInContext($ctx, () => processor(job, ...rest));
|
|
94
|
-
},
|
|
95
|
-
options
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
every(interval: string, name: string, data?: any, options?: any) {
|
|
100
|
-
return this.pulse.every(interval, name, data, options);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
schedule(when: Date | string, name: string, data?: any) {
|
|
104
|
-
return this.pulse.schedule(when, name, data);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
now(name: string, data?: any) {
|
|
108
|
-
return this.pulse.now(name, data);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
create(name: string, data?: any) {
|
|
112
|
-
return this.pulse.create(name, data);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
protected getProviders(): Provider<any>[] {
|
|
116
|
-
return this.injector.getProviders(PROVIDER_TYPE_PULSE);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
protected addPulseDefinitionsForProvider(provider: Provider): void {
|
|
120
|
-
const store = provider.store.get<PulseStore>("pulse", {});
|
|
121
|
-
|
|
122
|
-
if (!store.define) {
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
Object.entries(store.define).forEach(([propertyKey, {name, ...options}]) => {
|
|
127
|
-
const instance = this.injector.get(provider.token);
|
|
128
|
-
|
|
129
|
-
const jobProcessor: Processor<never> = instance[propertyKey].bind(instance) as Processor<never>;
|
|
130
|
-
const jobName = this.getNameForJob(propertyKey, store.namespace, name);
|
|
131
|
-
|
|
132
|
-
this.define(jobName, jobProcessor, options);
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
protected async scheduleJobsForProvider(provider: Provider<any>): Promise<void> {
|
|
137
|
-
const store = provider.store.get<PulseStore>("pulse", {});
|
|
138
|
-
|
|
139
|
-
if (!store.every) {
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
const promises = Object.entries(store.every).map(([propertyKey, {interval, name, ...options}]) => {
|
|
144
|
-
const jobName = this.getNameForJob(propertyKey, store.namespace, name);
|
|
145
|
-
|
|
146
|
-
return this.every(interval, jobName, {}, options);
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
await Promise.all(promises);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
protected getNameForJob(propertyKey: string, namespace?: string, customName?: string): string {
|
|
153
|
-
const name = customName || propertyKey;
|
|
154
|
-
return namespace ? `${namespace}.${name}` : name;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const PROVIDER_TYPE_PULSE = "PROVIDER_TYPE_PULSE";
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import {Store} from "@tsed/core";
|
|
2
|
-
|
|
3
|
-
import {Define} from "./define.js";
|
|
4
|
-
import {Pulse} from "./pulse.js";
|
|
5
|
-
|
|
6
|
-
describe("@Define()", () => {
|
|
7
|
-
it("should set empty metadata", () => {
|
|
8
|
-
@Pulse()
|
|
9
|
-
class Test {
|
|
10
|
-
@Define()
|
|
11
|
-
testDefineDecorator() {
|
|
12
|
-
// test
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
@Define()
|
|
16
|
-
testDefineDecorator2() {
|
|
17
|
-
// test 2
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const store = Store.from(Test);
|
|
22
|
-
|
|
23
|
-
expect(store.get("pulse").define).toEqual({
|
|
24
|
-
testDefineDecorator: {},
|
|
25
|
-
testDefineDecorator2: {}
|
|
26
|
-
});
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it("should set options metadata", () => {
|
|
30
|
-
@Pulse()
|
|
31
|
-
class Test {
|
|
32
|
-
@Define({
|
|
33
|
-
name: "testDefineDecoratorCustomName",
|
|
34
|
-
priority: "highest"
|
|
35
|
-
})
|
|
36
|
-
test() {
|
|
37
|
-
// test
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const store = Store.from(Test);
|
|
42
|
-
expect(store.get("pulse").define).toEqual({
|
|
43
|
-
test: {
|
|
44
|
-
name: "testDefineDecoratorCustomName",
|
|
45
|
-
priority: "highest"
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
|
-
});
|
package/src/decorators/define.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import {Store} from "@tsed/core";
|
|
2
|
-
|
|
3
|
-
import {DefineOptions, PulseStore} from "../interfaces/PulseStore.js";
|
|
4
|
-
|
|
5
|
-
export function Define(options: DefineOptions = {}): MethodDecorator {
|
|
6
|
-
return (target: any, propertyKey: string) => {
|
|
7
|
-
const store: PulseStore = {
|
|
8
|
-
define: {
|
|
9
|
-
[propertyKey]: options
|
|
10
|
-
}
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
Store.from(target).merge("pulse", store);
|
|
14
|
-
};
|
|
15
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import {Store} from "@tsed/core";
|
|
2
|
-
|
|
3
|
-
import {Every} from "./every.js";
|
|
4
|
-
import {Pulse} from "./pulse.js";
|
|
5
|
-
|
|
6
|
-
describe("@Every()", () => {
|
|
7
|
-
it("should set metadata", () => {
|
|
8
|
-
@Pulse()
|
|
9
|
-
class Test {
|
|
10
|
-
@Every("60 seconds")
|
|
11
|
-
testEveryDecorator() {
|
|
12
|
-
// test
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
@Every("* * * * *")
|
|
16
|
-
testEveryDecorator2() {
|
|
17
|
-
// test 2
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const store = Store.from(Test);
|
|
22
|
-
|
|
23
|
-
expect(store.get("pulse").define).toEqual({
|
|
24
|
-
testEveryDecorator: {},
|
|
25
|
-
testEveryDecorator2: {}
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
expect(store.get("pulse").every).toEqual({
|
|
29
|
-
testEveryDecorator: {
|
|
30
|
-
interval: "60 seconds"
|
|
31
|
-
},
|
|
32
|
-
testEveryDecorator2: {
|
|
33
|
-
interval: "* * * * *"
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
});
|
package/src/decorators/every.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import {Store, useDecorators} from "@tsed/core";
|
|
2
|
-
|
|
3
|
-
import {EveryOptions, PulseStore} from "../interfaces/PulseStore.js";
|
|
4
|
-
import {Define} from "./define.js";
|
|
5
|
-
|
|
6
|
-
export function Every(interval: string, options: EveryOptions = {}): MethodDecorator {
|
|
7
|
-
return useDecorators(Define(options), (target: any, propertyKey: string) => {
|
|
8
|
-
const store: PulseStore = {
|
|
9
|
-
every: {
|
|
10
|
-
[propertyKey]: {...options, interval}
|
|
11
|
-
}
|
|
12
|
-
};
|
|
13
|
-
Store.from(target).merge("pulse", store);
|
|
14
|
-
});
|
|
15
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import {Store} from "@tsed/core";
|
|
2
|
-
|
|
3
|
-
import {Pulse} from "./pulse.js";
|
|
4
|
-
|
|
5
|
-
describe("@Pulse()", () => {
|
|
6
|
-
it("should set empty metadata", () => {
|
|
7
|
-
@Pulse()
|
|
8
|
-
class Test {}
|
|
9
|
-
|
|
10
|
-
const store = Store.from(Test);
|
|
11
|
-
expect(store.get("pulse")).toEqual(undefined);
|
|
12
|
-
});
|
|
13
|
-
it("should set namespace metadata", () => {
|
|
14
|
-
@Pulse({namespace: "nsp1"})
|
|
15
|
-
class Test {}
|
|
16
|
-
|
|
17
|
-
const store = Store.from(Test);
|
|
18
|
-
expect(store.get("pulse")).toEqual({
|
|
19
|
-
namespace: "nsp1"
|
|
20
|
-
});
|
|
21
|
-
});
|
|
22
|
-
});
|
package/src/decorators/pulse.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import {StoreMerge, useDecorators} from "@tsed/core";
|
|
2
|
-
import {Injectable} from "@tsed/di";
|
|
3
|
-
|
|
4
|
-
import {PROVIDER_TYPE_PULSE} from "../constants/constants.js";
|
|
5
|
-
|
|
6
|
-
interface PulseOptions {
|
|
7
|
-
namespace?: string;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function Pulse(options?: PulseOptions): ClassDecorator {
|
|
11
|
-
return useDecorators(
|
|
12
|
-
options?.namespace && StoreMerge("pulse", options),
|
|
13
|
-
Injectable({
|
|
14
|
-
type: PROVIDER_TYPE_PULSE
|
|
15
|
-
})
|
|
16
|
-
);
|
|
17
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file Automatically generated by @tsed/barrels.
|
|
3
|
-
*/
|
|
4
|
-
export * from "./constants/constants.js";
|
|
5
|
-
export * from "./decorators/define.js";
|
|
6
|
-
export * from "./decorators/every.js";
|
|
7
|
-
export * from "./decorators/pulse.js";
|
|
8
|
-
export * from "./interfaces/interfaces.js";
|
|
9
|
-
export * from "./interfaces/PulseStore.js";
|
|
10
|
-
export * from "./PulseModule.js";
|
|
11
|
-
export * from "./services/PulseFactory.js";
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import {DefineOptions as PulseDefineOptions, JobOptions} from "@pulsecron/pulse";
|
|
2
|
-
|
|
3
|
-
export interface DefineOptions extends PulseDefineOptions {
|
|
4
|
-
name?: string;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export type EveryOptions = JobOptions & DefineOptions;
|
|
8
|
-
|
|
9
|
-
export interface PulseStore {
|
|
10
|
-
namespace?: string;
|
|
11
|
-
define?: {[propertyKey: string]: DefineOptions};
|
|
12
|
-
every?: {[propertyKey: string]: EveryOptions & {interval: string}};
|
|
13
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import {PulseConfig} from "@pulsecron/pulse";
|
|
2
|
-
|
|
3
|
-
declare global {
|
|
4
|
-
namespace TsED {
|
|
5
|
-
interface Configuration {
|
|
6
|
-
pulse?: {
|
|
7
|
-
/**
|
|
8
|
-
* Enable Pulse jobs. Default false.
|
|
9
|
-
*/
|
|
10
|
-
enabled?: boolean;
|
|
11
|
-
disableJobProcessing?: boolean;
|
|
12
|
-
drainJobsBeforeClose?: boolean;
|
|
13
|
-
} & PulseConfig;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import {Pulse, PulseConfig} from "@pulsecron/pulse";
|
|
2
|
-
import {Configuration, registerProvider} from "@tsed/di";
|
|
3
|
-
|
|
4
|
-
// create Alias to avoid confusing import between Pulse from "@pulsecron/pulse" and Pulse decorator
|
|
5
|
-
export const PulseService = Pulse;
|
|
6
|
-
export type PulseService = Pulse;
|
|
7
|
-
|
|
8
|
-
registerProvider({
|
|
9
|
-
token: Pulse,
|
|
10
|
-
deps: [Configuration],
|
|
11
|
-
useFactory(settings: Configuration) {
|
|
12
|
-
const opts = settings.get<PulseConfig & {enabled: boolean}>("pulse", {enabled: false});
|
|
13
|
-
return opts.enabled ? new Pulse(opts) : {};
|
|
14
|
-
}
|
|
15
|
-
});
|
package/vitest.config.mts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
// @ts-ignore
|
|
2
|
-
import {presets} from "@tsed/vitest/presets";
|
|
3
|
-
import {defineConfig} from "vitest/config";
|
|
4
|
-
|
|
5
|
-
export default defineConfig(
|
|
6
|
-
{
|
|
7
|
-
...presets,
|
|
8
|
-
test: {
|
|
9
|
-
...presets.test,
|
|
10
|
-
// @ts-ignore
|
|
11
|
-
globalSetup: [
|
|
12
|
-
"../../orm/testcontainers-mongo/src/setup/vi.setup.ts"
|
|
13
|
-
],
|
|
14
|
-
coverage: {
|
|
15
|
-
...presets.test.coverage,
|
|
16
|
-
thresholds: {
|
|
17
|
-
statements: 0,
|
|
18
|
-
branches: 0,
|
|
19
|
-
functions: 0,
|
|
20
|
-
lines: 0
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
);
|