@quave/agenda 1.0.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.
Files changed (216) hide show
  1. package/LICENSE.md +25 -0
  2. package/README.md +380 -0
  3. package/dist/Job.d.ts +190 -0
  4. package/dist/Job.js +689 -0
  5. package/dist/Job.js.map +1 -0
  6. package/dist/JobProcessingQueue.d.ts +47 -0
  7. package/dist/JobProcessingQueue.js +107 -0
  8. package/dist/JobProcessingQueue.js.map +1 -0
  9. package/dist/JobProcessor.d.ts +72 -0
  10. package/dist/JobProcessor.js +512 -0
  11. package/dist/JobProcessor.js.map +1 -0
  12. package/dist/backends/index.d.ts +18 -0
  13. package/dist/backends/index.js +20 -0
  14. package/dist/backends/index.js.map +1 -0
  15. package/dist/cjs/Job.d.ts +190 -0
  16. package/dist/cjs/Job.js +696 -0
  17. package/dist/cjs/Job.js.map +1 -0
  18. package/dist/cjs/JobProcessingQueue.d.ts +47 -0
  19. package/dist/cjs/JobProcessingQueue.js +111 -0
  20. package/dist/cjs/JobProcessingQueue.js.map +1 -0
  21. package/dist/cjs/JobProcessor.d.ts +72 -0
  22. package/dist/cjs/JobProcessor.js +519 -0
  23. package/dist/cjs/JobProcessor.js.map +1 -0
  24. package/dist/cjs/backends/index.d.ts +17 -0
  25. package/dist/cjs/backends/index.js +20 -0
  26. package/dist/cjs/backends/index.js.map +1 -0
  27. package/dist/cjs/decorators/Define.d.ts +33 -0
  28. package/dist/cjs/decorators/Define.js +47 -0
  29. package/dist/cjs/decorators/Define.js.map +1 -0
  30. package/dist/cjs/decorators/Every.d.ts +43 -0
  31. package/dist/cjs/decorators/Every.js +58 -0
  32. package/dist/cjs/decorators/Every.js.map +1 -0
  33. package/dist/cjs/decorators/JobsController.d.ts +43 -0
  34. package/dist/cjs/decorators/JobsController.js +40 -0
  35. package/dist/cjs/decorators/JobsController.js.map +1 -0
  36. package/dist/cjs/decorators/index.d.ts +41 -0
  37. package/dist/cjs/decorators/index.js +57 -0
  38. package/dist/cjs/decorators/index.js.map +1 -0
  39. package/dist/cjs/decorators/metadata.d.ts +50 -0
  40. package/dist/cjs/decorators/metadata.js +41 -0
  41. package/dist/cjs/decorators/metadata.js.map +1 -0
  42. package/dist/cjs/decorators/register.d.ts +52 -0
  43. package/dist/cjs/decorators/register.js +145 -0
  44. package/dist/cjs/decorators/register.js.map +1 -0
  45. package/dist/cjs/index.d.ts +498 -0
  46. package/dist/cjs/index.js +776 -0
  47. package/dist/cjs/index.js.map +1 -0
  48. package/dist/cjs/notifications/BaseNotificationChannel.d.ts +47 -0
  49. package/dist/cjs/notifications/BaseNotificationChannel.js +112 -0
  50. package/dist/cjs/notifications/BaseNotificationChannel.js.map +1 -0
  51. package/dist/cjs/notifications/InMemoryNotificationChannel.d.ts +13 -0
  52. package/dist/cjs/notifications/InMemoryNotificationChannel.js +37 -0
  53. package/dist/cjs/notifications/InMemoryNotificationChannel.js.map +1 -0
  54. package/dist/cjs/notifications/index.d.ts +2 -0
  55. package/dist/cjs/notifications/index.js +8 -0
  56. package/dist/cjs/notifications/index.js.map +1 -0
  57. package/dist/cjs/package.json +1 -0
  58. package/dist/cjs/types/AgendaBackend.d.ts +61 -0
  59. package/dist/cjs/types/AgendaBackend.js +3 -0
  60. package/dist/cjs/types/AgendaBackend.js.map +1 -0
  61. package/dist/cjs/types/AgendaConfig.d.ts +10 -0
  62. package/dist/cjs/types/AgendaConfig.js +3 -0
  63. package/dist/cjs/types/AgendaConfig.js.map +1 -0
  64. package/dist/cjs/types/AgendaStatus.d.ts +32 -0
  65. package/dist/cjs/types/AgendaStatus.js +3 -0
  66. package/dist/cjs/types/AgendaStatus.js.map +1 -0
  67. package/dist/cjs/types/DbOptions.d.ts +4 -0
  68. package/dist/cjs/types/DbOptions.js +3 -0
  69. package/dist/cjs/types/DbOptions.js.map +1 -0
  70. package/dist/cjs/types/DrainOptions.d.ts +37 -0
  71. package/dist/cjs/types/DrainOptions.js +3 -0
  72. package/dist/cjs/types/DrainOptions.js.map +1 -0
  73. package/dist/cjs/types/JobDefinition.d.ts +49 -0
  74. package/dist/cjs/types/JobDefinition.js +3 -0
  75. package/dist/cjs/types/JobDefinition.js.map +1 -0
  76. package/dist/cjs/types/JobLogger.d.ts +111 -0
  77. package/dist/cjs/types/JobLogger.js +3 -0
  78. package/dist/cjs/types/JobLogger.js.map +1 -0
  79. package/dist/cjs/types/JobParameters.d.ts +106 -0
  80. package/dist/cjs/types/JobParameters.js +21 -0
  81. package/dist/cjs/types/JobParameters.js.map +1 -0
  82. package/dist/cjs/types/JobQuery.d.ts +79 -0
  83. package/dist/cjs/types/JobQuery.js +36 -0
  84. package/dist/cjs/types/JobQuery.js.map +1 -0
  85. package/dist/cjs/types/JobRepository.d.ts +101 -0
  86. package/dist/cjs/types/JobRepository.js +3 -0
  87. package/dist/cjs/types/JobRepository.js.map +1 -0
  88. package/dist/cjs/types/NotificationChannel.d.ts +120 -0
  89. package/dist/cjs/types/NotificationChannel.js +3 -0
  90. package/dist/cjs/types/NotificationChannel.js.map +1 -0
  91. package/dist/cjs/utils/backoff.d.ts +152 -0
  92. package/dist/cjs/utils/backoff.js +175 -0
  93. package/dist/cjs/utils/backoff.js.map +1 -0
  94. package/dist/cjs/utils/dateConstraints.d.ts +48 -0
  95. package/dist/cjs/utils/dateConstraints.js +127 -0
  96. package/dist/cjs/utils/dateConstraints.js.map +1 -0
  97. package/dist/cjs/utils/isValidDate.d.ts +1 -0
  98. package/dist/cjs/utils/isValidDate.js +8 -0
  99. package/dist/cjs/utils/isValidDate.js.map +1 -0
  100. package/dist/cjs/utils/nextRunAt.d.ts +10 -0
  101. package/dist/cjs/utils/nextRunAt.js +119 -0
  102. package/dist/cjs/utils/nextRunAt.js.map +1 -0
  103. package/dist/cjs/utils/priority.d.ts +13 -0
  104. package/dist/cjs/utils/priority.js +23 -0
  105. package/dist/cjs/utils/priority.js.map +1 -0
  106. package/dist/cjs/utils/processEvery.d.ts +1 -0
  107. package/dist/cjs/utils/processEvery.js +13 -0
  108. package/dist/cjs/utils/processEvery.js.map +1 -0
  109. package/dist/cjs/utils/stack.d.ts +1 -0
  110. package/dist/cjs/utils/stack.js +21 -0
  111. package/dist/cjs/utils/stack.js.map +1 -0
  112. package/dist/cjs/version.d.ts +9 -0
  113. package/dist/cjs/version.js +13 -0
  114. package/dist/cjs/version.js.map +1 -0
  115. package/dist/decorators/Define.d.ts +33 -0
  116. package/dist/decorators/Define.js +44 -0
  117. package/dist/decorators/Define.js.map +1 -0
  118. package/dist/decorators/Every.d.ts +43 -0
  119. package/dist/decorators/Every.js +55 -0
  120. package/dist/decorators/Every.js.map +1 -0
  121. package/dist/decorators/JobsController.d.ts +43 -0
  122. package/dist/decorators/JobsController.js +37 -0
  123. package/dist/decorators/JobsController.js.map +1 -0
  124. package/dist/decorators/index.d.ts +41 -0
  125. package/dist/decorators/index.js +46 -0
  126. package/dist/decorators/index.js.map +1 -0
  127. package/dist/decorators/metadata.d.ts +50 -0
  128. package/dist/decorators/metadata.js +35 -0
  129. package/dist/decorators/metadata.js.map +1 -0
  130. package/dist/decorators/register.d.ts +52 -0
  131. package/dist/decorators/register.js +139 -0
  132. package/dist/decorators/register.js.map +1 -0
  133. package/dist/index.d.ts +498 -0
  134. package/dist/index.js +744 -0
  135. package/dist/index.js.map +1 -0
  136. package/dist/notifications/BaseNotificationChannel.d.ts +47 -0
  137. package/dist/notifications/BaseNotificationChannel.js +108 -0
  138. package/dist/notifications/BaseNotificationChannel.js.map +1 -0
  139. package/dist/notifications/InMemoryNotificationChannel.d.ts +13 -0
  140. package/dist/notifications/InMemoryNotificationChannel.js +33 -0
  141. package/dist/notifications/InMemoryNotificationChannel.js.map +1 -0
  142. package/dist/notifications/index.d.ts +2 -0
  143. package/dist/notifications/index.js +3 -0
  144. package/dist/notifications/index.js.map +1 -0
  145. package/dist/types/AgendaBackend.d.ts +61 -0
  146. package/dist/types/AgendaBackend.js +2 -0
  147. package/dist/types/AgendaBackend.js.map +1 -0
  148. package/dist/types/AgendaConfig.d.ts +10 -0
  149. package/dist/types/AgendaConfig.js +2 -0
  150. package/dist/types/AgendaConfig.js.map +1 -0
  151. package/dist/types/AgendaStatus.d.ts +32 -0
  152. package/dist/types/AgendaStatus.js +2 -0
  153. package/dist/types/AgendaStatus.js.map +1 -0
  154. package/dist/types/DbOptions.d.ts +4 -0
  155. package/dist/types/DbOptions.js +2 -0
  156. package/dist/types/DbOptions.js.map +1 -0
  157. package/dist/types/DrainOptions.d.ts +37 -0
  158. package/dist/types/DrainOptions.js +2 -0
  159. package/dist/types/DrainOptions.js.map +1 -0
  160. package/dist/types/JobDefinition.d.ts +49 -0
  161. package/dist/types/JobDefinition.js +2 -0
  162. package/dist/types/JobDefinition.js.map +1 -0
  163. package/dist/types/JobLogger.d.ts +111 -0
  164. package/dist/types/JobLogger.js +2 -0
  165. package/dist/types/JobLogger.js.map +1 -0
  166. package/dist/types/JobParameters.d.ts +106 -0
  167. package/dist/types/JobParameters.js +17 -0
  168. package/dist/types/JobParameters.js.map +1 -0
  169. package/dist/types/JobQuery.d.ts +79 -0
  170. package/dist/types/JobQuery.js +33 -0
  171. package/dist/types/JobQuery.js.map +1 -0
  172. package/dist/types/JobRepository.d.ts +101 -0
  173. package/dist/types/JobRepository.js +2 -0
  174. package/dist/types/JobRepository.js.map +1 -0
  175. package/dist/types/NotificationChannel.d.ts +120 -0
  176. package/dist/types/NotificationChannel.js +2 -0
  177. package/dist/types/NotificationChannel.js.map +1 -0
  178. package/dist/utils/backoff.d.ts +152 -0
  179. package/dist/utils/backoff.js +167 -0
  180. package/dist/utils/backoff.js.map +1 -0
  181. package/dist/utils/dateConstraints.d.ts +48 -0
  182. package/dist/utils/dateConstraints.js +117 -0
  183. package/dist/utils/dateConstraints.js.map +1 -0
  184. package/dist/utils/isValidDate.d.ts +1 -0
  185. package/dist/utils/isValidDate.js +5 -0
  186. package/dist/utils/isValidDate.js.map +1 -0
  187. package/dist/utils/nextRunAt.d.ts +10 -0
  188. package/dist/utils/nextRunAt.js +110 -0
  189. package/dist/utils/nextRunAt.js.map +1 -0
  190. package/dist/utils/priority.d.ts +13 -0
  191. package/dist/utils/priority.js +20 -0
  192. package/dist/utils/priority.js.map +1 -0
  193. package/dist/utils/processEvery.d.ts +1 -0
  194. package/dist/utils/processEvery.js +7 -0
  195. package/dist/utils/processEvery.js.map +1 -0
  196. package/dist/utils/stack.d.ts +1 -0
  197. package/dist/utils/stack.js +18 -0
  198. package/dist/utils/stack.js.map +1 -0
  199. package/dist/version.d.ts +9 -0
  200. package/dist/version.js +10 -0
  201. package/dist/version.js.map +1 -0
  202. package/package.json +79 -0
  203. package/test/fixtures/forkHelper.js +40 -0
  204. package/test/fixtures/someJobDefinition.ts +12 -0
  205. package/test/shared/agenda-test-suite.ts +1876 -0
  206. package/test/shared/backoff-test-suite.ts +408 -0
  207. package/test/shared/debounce-test-suite.ts +377 -0
  208. package/test/shared/full-test-suite.ts +161 -0
  209. package/test/shared/index.ts +50 -0
  210. package/test/shared/joblogger-test-suite.ts +305 -0
  211. package/test/shared/jobprocessor-test-suite.ts +266 -0
  212. package/test/shared/notification-channel-test-suite.ts +471 -0
  213. package/test/shared/removeoncomplete-test-suite.ts +228 -0
  214. package/test/shared/repository-test-suite.ts +708 -0
  215. package/test/shared/retry-test-suite.ts +174 -0
  216. package/test/shared/test-utils.ts +100 -0
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Define = Define;
4
+ const metadata_js_1 = require("./metadata.js");
5
+ /**
6
+ * Method decorator that defines a job handler.
7
+ *
8
+ * Jobs decorated with @Define must be scheduled programmatically using
9
+ * `agenda.now()`, `agenda.schedule()`, or `agenda.every()`.
10
+ *
11
+ * @param options - Configuration options for the job definition
12
+ * @returns Method decorator
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * import { JobsController, Define, Job } from 'agenda';
17
+ *
18
+ * @JobsController()
19
+ * class EmailJobs {
20
+ * @Define({
21
+ * name: 'sendWelcome',
22
+ * concurrency: 5,
23
+ * priority: 'high'
24
+ * })
25
+ * async sendWelcomeEmail(job: Job<{ userId: string; template: string }>) {
26
+ * const { userId, template } = job.attrs.data;
27
+ * await this.emailService.send(userId, template);
28
+ * }
29
+ * }
30
+ *
31
+ * // Later, schedule the job:
32
+ * await agenda.now('sendWelcome', { userId: '123', template: 'welcome' });
33
+ * ```
34
+ */
35
+ function Define(options = {}) {
36
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Standard decorator signature requires any for target
37
+ return function (target, propertyKey, descriptor) {
38
+ const metadata = (0, metadata_js_1.getOrCreateControllerMetadata)(target.constructor);
39
+ metadata.jobs.set(propertyKey, {
40
+ type: 'define',
41
+ methodName: propertyKey,
42
+ options
43
+ });
44
+ return descriptor;
45
+ };
46
+ }
47
+ //# sourceMappingURL=Define.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Define.js","sourceRoot":"","sources":["../../../src/decorators/Define.ts"],"names":[],"mappings":";;AAkCA,wBAaC;AA/CD,+CAAkF;AAIlF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,SAAgB,MAAM,CAAC,UAAyB,EAAE;IACjD,sHAAsH;IACtH,OAAO,UAAU,MAAW,EAAE,WAAmB,EAAE,UAA8B;QAChF,MAAM,QAAQ,GAAG,IAAA,2CAA6B,EAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAEnE,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE;YAC9B,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,WAAW;YACvB,OAAO;SACP,CAAC,CAAC;QAEH,OAAO,UAAU,CAAC;IACnB,CAAC,CAAC;AACH,CAAC"}
@@ -0,0 +1,43 @@
1
+ import { type EveryOptions } from './metadata.js';
2
+ export type { EveryOptions };
3
+ /**
4
+ * Method decorator that defines a recurring job.
5
+ *
6
+ * Jobs decorated with @Every are automatically scheduled when registered
7
+ * with the Agenda instance. They will run at the specified interval.
8
+ *
9
+ * @param interval - The interval at which the job should run.
10
+ * Can be a cron expression, human-readable string, or milliseconds.
11
+ * @param options - Configuration options for the job
12
+ * @returns Method decorator
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * import { JobsController, Every, Job } from 'agenda';
17
+ *
18
+ * @JobsController({ namespace: 'maintenance' })
19
+ * class MaintenanceJobs {
20
+ * // Run every 5 minutes
21
+ * @Every('5 minutes')
22
+ * async healthCheck(job: Job) {
23
+ * await this.checkSystemHealth();
24
+ * }
25
+ *
26
+ * // Run daily at midnight using cron
27
+ * @Every('0 0 * * *', {
28
+ * name: 'dailyCleanup',
29
+ * timezone: 'America/New_York'
30
+ * })
31
+ * async cleanupOldData(job: Job) {
32
+ * await this.deleteOldRecords();
33
+ * }
34
+ *
35
+ * // Run every hour with high priority
36
+ * @Every('1 hour', { priority: 'high', concurrency: 1 })
37
+ * async generateReport(job: Job) {
38
+ * await this.createHourlyReport();
39
+ * }
40
+ * }
41
+ * ```
42
+ */
43
+ export declare function Every(interval: string | number, options?: EveryOptions): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Every = Every;
4
+ const metadata_js_1 = require("./metadata.js");
5
+ /**
6
+ * Method decorator that defines a recurring job.
7
+ *
8
+ * Jobs decorated with @Every are automatically scheduled when registered
9
+ * with the Agenda instance. They will run at the specified interval.
10
+ *
11
+ * @param interval - The interval at which the job should run.
12
+ * Can be a cron expression, human-readable string, or milliseconds.
13
+ * @param options - Configuration options for the job
14
+ * @returns Method decorator
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * import { JobsController, Every, Job } from 'agenda';
19
+ *
20
+ * @JobsController({ namespace: 'maintenance' })
21
+ * class MaintenanceJobs {
22
+ * // Run every 5 minutes
23
+ * @Every('5 minutes')
24
+ * async healthCheck(job: Job) {
25
+ * await this.checkSystemHealth();
26
+ * }
27
+ *
28
+ * // Run daily at midnight using cron
29
+ * @Every('0 0 * * *', {
30
+ * name: 'dailyCleanup',
31
+ * timezone: 'America/New_York'
32
+ * })
33
+ * async cleanupOldData(job: Job) {
34
+ * await this.deleteOldRecords();
35
+ * }
36
+ *
37
+ * // Run every hour with high priority
38
+ * @Every('1 hour', { priority: 'high', concurrency: 1 })
39
+ * async generateReport(job: Job) {
40
+ * await this.createHourlyReport();
41
+ * }
42
+ * }
43
+ * ```
44
+ */
45
+ function Every(interval, options = {}) {
46
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Standard decorator signature requires any for target
47
+ return function (target, propertyKey, descriptor) {
48
+ const metadata = (0, metadata_js_1.getOrCreateControllerMetadata)(target.constructor);
49
+ metadata.jobs.set(propertyKey, {
50
+ type: 'every',
51
+ methodName: propertyKey,
52
+ interval,
53
+ options
54
+ });
55
+ return descriptor;
56
+ };
57
+ }
58
+ //# sourceMappingURL=Every.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Every.js","sourceRoot":"","sources":["../../../src/decorators/Every.ts"],"names":[],"mappings":";;AA4CA,sBAcC;AA1DD,+CAAiF;AAIjF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,SAAgB,KAAK,CAAC,QAAyB,EAAE,UAAwB,EAAE;IAC1E,sHAAsH;IACtH,OAAO,UAAU,MAAW,EAAE,WAAmB,EAAE,UAA8B;QAChF,MAAM,QAAQ,GAAG,IAAA,2CAA6B,EAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAEnE,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE;YAC9B,IAAI,EAAE,OAAO;YACb,UAAU,EAAE,WAAW;YACvB,QAAQ;YACR,OAAO;SACP,CAAC,CAAC;QAEH,OAAO,UAAU,CAAC;IACnB,CAAC,CAAC;AACH,CAAC"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Options for the @JobsController decorator
3
+ */
4
+ export interface JobsControllerOptions {
5
+ /**
6
+ * Namespace prefix for all jobs in this class.
7
+ * Job names will be formatted as "namespace.jobName"
8
+ * @example
9
+ * ```typescript
10
+ * @JobsController({ namespace: 'email' })
11
+ * class EmailJobs {
12
+ * @Define()
13
+ * async sendWelcome(job: Job) {} // registered as "email.sendWelcome"
14
+ * }
15
+ * ```
16
+ */
17
+ namespace?: string;
18
+ }
19
+ /**
20
+ * Class decorator that marks a class as containing job handlers.
21
+ *
22
+ * @param options - Configuration options for the jobs controller
23
+ * @returns Class decorator
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * import { JobsController, Define, Every } from 'agenda';
28
+ *
29
+ * @JobsController({ namespace: 'notifications' })
30
+ * class NotificationJobs {
31
+ * @Define()
32
+ * async sendPush(job: Job<{ userId: string }>) {
33
+ * // Handle push notification
34
+ * }
35
+ *
36
+ * @Every('5 minutes')
37
+ * async checkPending(job: Job) {
38
+ * // Check for pending notifications
39
+ * }
40
+ * }
41
+ * ```
42
+ */
43
+ export declare function JobsController(options?: JobsControllerOptions): <T extends new (...args: any[]) => any>(target: T) => T;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JobsController = JobsController;
4
+ const metadata_js_1 = require("./metadata.js");
5
+ /**
6
+ * Class decorator that marks a class as containing job handlers.
7
+ *
8
+ * @param options - Configuration options for the jobs controller
9
+ * @returns Class decorator
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * import { JobsController, Define, Every } from 'agenda';
14
+ *
15
+ * @JobsController({ namespace: 'notifications' })
16
+ * class NotificationJobs {
17
+ * @Define()
18
+ * async sendPush(job: Job<{ userId: string }>) {
19
+ * // Handle push notification
20
+ * }
21
+ *
22
+ * @Every('5 minutes')
23
+ * async checkPending(job: Job) {
24
+ * // Check for pending notifications
25
+ * }
26
+ * }
27
+ * ```
28
+ */
29
+ function JobsController(options = {}) {
30
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Standard class decorator signature requires any
31
+ return function (target) {
32
+ const metadata = (0, metadata_js_1.getOrCreateControllerMetadata)(target);
33
+ (0, metadata_js_1.setControllerMetadata)(target, {
34
+ ...metadata,
35
+ namespace: options.namespace
36
+ });
37
+ return target;
38
+ };
39
+ }
40
+ //# sourceMappingURL=JobsController.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JobsController.js","sourceRoot":"","sources":["../../../src/decorators/JobsController.ts"],"names":[],"mappings":";;AA6CA,wCAUC;AAvDD,+CAAqF;AAqBrF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,SAAgB,cAAc,CAAC,UAAiC,EAAE;IACjE,iHAAiH;IACjH,OAAO,UAAiD,MAAS;QAChE,MAAM,QAAQ,GAAG,IAAA,2CAA6B,EAAC,MAAM,CAAC,CAAC;QACvD,IAAA,mCAAqB,EAAC,MAAM,EAAE;YAC7B,GAAG,QAAQ;YACX,SAAS,EAAE,OAAO,CAAC,SAAS;SAC5B,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IACf,CAAC,CAAC;AACH,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Agenda Decorators
3
+ *
4
+ * TypeScript decorators for defining job handlers in a declarative way.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { Agenda, JobsController, Define, Every, registerJobs, Job } from 'agenda';
9
+ * import { MongoBackend } from '@quave/agenda-mongodb';
10
+ *
11
+ * @JobsController({ namespace: 'email' })
12
+ * class EmailJobs {
13
+ * @Define({ concurrency: 5 })
14
+ * async sendWelcome(job: Job<{ userId: string }>) {
15
+ * // Send welcome email
16
+ * }
17
+ *
18
+ * @Every('1 hour')
19
+ * async cleanupBounced(job: Job) {
20
+ * // Cleanup bounced emails
21
+ * }
22
+ * }
23
+ *
24
+ * const agenda = new Agenda({
25
+ * backend: new MongoBackend({ address: 'mongodb://localhost/agenda' })
26
+ * });
27
+ *
28
+ * registerJobs(agenda, [new EmailJobs()]);
29
+ * await agenda.start();
30
+ *
31
+ * // Schedule a job
32
+ * await agenda.now('email.sendWelcome', { userId: '123' });
33
+ * ```
34
+ *
35
+ * @module decorators
36
+ */
37
+ export { JobsController, type JobsControllerOptions } from './JobsController.js';
38
+ export { Define, type DefineOptions } from './Define.js';
39
+ export { Every, type EveryOptions } from './Every.js';
40
+ export { registerJobs, getRegisteredJobsInfo, JobsRegistrationError } from './register.js';
41
+ export { getControllerMetadata, isJobsController, type ControllerMetadata, type JobMetadata, type ScheduleOptions } from './metadata.js';
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ /**
3
+ * Agenda Decorators
4
+ *
5
+ * TypeScript decorators for defining job handlers in a declarative way.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { Agenda, JobsController, Define, Every, registerJobs, Job } from 'agenda';
10
+ * import { MongoBackend } from '@quave/agenda-mongodb';
11
+ *
12
+ * @JobsController({ namespace: 'email' })
13
+ * class EmailJobs {
14
+ * @Define({ concurrency: 5 })
15
+ * async sendWelcome(job: Job<{ userId: string }>) {
16
+ * // Send welcome email
17
+ * }
18
+ *
19
+ * @Every('1 hour')
20
+ * async cleanupBounced(job: Job) {
21
+ * // Cleanup bounced emails
22
+ * }
23
+ * }
24
+ *
25
+ * const agenda = new Agenda({
26
+ * backend: new MongoBackend({ address: 'mongodb://localhost/agenda' })
27
+ * });
28
+ *
29
+ * registerJobs(agenda, [new EmailJobs()]);
30
+ * await agenda.start();
31
+ *
32
+ * // Schedule a job
33
+ * await agenda.now('email.sendWelcome', { userId: '123' });
34
+ * ```
35
+ *
36
+ * @module decorators
37
+ */
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.isJobsController = exports.getControllerMetadata = exports.JobsRegistrationError = exports.getRegisteredJobsInfo = exports.registerJobs = exports.Every = exports.Define = exports.JobsController = void 0;
40
+ // Class decorator
41
+ var JobsController_js_1 = require("./JobsController.js");
42
+ Object.defineProperty(exports, "JobsController", { enumerable: true, get: function () { return JobsController_js_1.JobsController; } });
43
+ // Method decorators
44
+ var Define_js_1 = require("./Define.js");
45
+ Object.defineProperty(exports, "Define", { enumerable: true, get: function () { return Define_js_1.Define; } });
46
+ var Every_js_1 = require("./Every.js");
47
+ Object.defineProperty(exports, "Every", { enumerable: true, get: function () { return Every_js_1.Every; } });
48
+ // Registration utilities
49
+ var register_js_1 = require("./register.js");
50
+ Object.defineProperty(exports, "registerJobs", { enumerable: true, get: function () { return register_js_1.registerJobs; } });
51
+ Object.defineProperty(exports, "getRegisteredJobsInfo", { enumerable: true, get: function () { return register_js_1.getRegisteredJobsInfo; } });
52
+ Object.defineProperty(exports, "JobsRegistrationError", { enumerable: true, get: function () { return register_js_1.JobsRegistrationError; } });
53
+ // Metadata utilities (for advanced use cases)
54
+ var metadata_js_1 = require("./metadata.js");
55
+ Object.defineProperty(exports, "getControllerMetadata", { enumerable: true, get: function () { return metadata_js_1.getControllerMetadata; } });
56
+ Object.defineProperty(exports, "isJobsController", { enumerable: true, get: function () { return metadata_js_1.isJobsController; } });
57
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/decorators/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;;;AAEH,kBAAkB;AAClB,yDAAiF;AAAxE,mHAAA,cAAc,OAAA;AAEvB,oBAAoB;AACpB,yCAAyD;AAAhD,mGAAA,MAAM,OAAA;AACf,uCAAsD;AAA7C,iGAAA,KAAK,OAAA;AAEd,yBAAyB;AACzB,6CAA2F;AAAlF,2GAAA,YAAY,OAAA;AAAE,oHAAA,qBAAqB,OAAA;AAAE,oHAAA,qBAAqB,OAAA;AAEnE,8CAA8C;AAC9C,6CAMuB;AALtB,oHAAA,qBAAqB,OAAA;AACrB,+GAAA,gBAAgB,OAAA"}
@@ -0,0 +1,50 @@
1
+ import type { JobPriority } from '../utils/priority.js';
2
+ /**
3
+ * Metadata storage for job decorators
4
+ * Uses a WeakMap to avoid memory leaks and doesn't require reflect-metadata
5
+ */
6
+ export interface DefineOptions {
7
+ name?: string;
8
+ concurrency?: number;
9
+ lockLifetime?: number;
10
+ lockLimit?: number;
11
+ priority?: JobPriority;
12
+ }
13
+ export interface EveryOptions extends DefineOptions {
14
+ timezone?: string;
15
+ skipImmediate?: boolean;
16
+ }
17
+ export interface ScheduleOptions extends DefineOptions {
18
+ when?: string | Date;
19
+ }
20
+ export interface JobMetadata {
21
+ type: 'define' | 'every' | 'schedule';
22
+ methodName: string;
23
+ options: DefineOptions | EveryOptions | ScheduleOptions;
24
+ interval?: string | number;
25
+ }
26
+ export interface ControllerMetadata {
27
+ namespace?: string;
28
+ jobs: Map<string, JobMetadata>;
29
+ }
30
+ /**
31
+ * Type for class constructors used in decorator metadata
32
+ */
33
+ type Constructor = abstract new (...args: any[]) => any;
34
+ /**
35
+ * Get or create controller metadata for a class
36
+ */
37
+ export declare function getOrCreateControllerMetadata(target: Constructor): ControllerMetadata;
38
+ /**
39
+ * Get controller metadata for a class
40
+ */
41
+ export declare function getControllerMetadata(target: Constructor): ControllerMetadata | undefined;
42
+ /**
43
+ * Set controller metadata for a class
44
+ */
45
+ export declare function setControllerMetadata(target: Constructor, metadata: ControllerMetadata): void;
46
+ /**
47
+ * Check if a class is decorated with @JobsController
48
+ */
49
+ export declare function isJobsController(target: Constructor): boolean;
50
+ export {};
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getOrCreateControllerMetadata = getOrCreateControllerMetadata;
4
+ exports.getControllerMetadata = getControllerMetadata;
5
+ exports.setControllerMetadata = setControllerMetadata;
6
+ exports.isJobsController = isJobsController;
7
+ /**
8
+ * Registry for storing job controller metadata
9
+ * Uses WeakMap to allow garbage collection of unused classes
10
+ */
11
+ const controllerRegistry = new WeakMap();
12
+ /**
13
+ * Get or create controller metadata for a class
14
+ */
15
+ function getOrCreateControllerMetadata(target) {
16
+ let metadata = controllerRegistry.get(target);
17
+ if (!metadata) {
18
+ metadata = { jobs: new Map() };
19
+ controllerRegistry.set(target, metadata);
20
+ }
21
+ return metadata;
22
+ }
23
+ /**
24
+ * Get controller metadata for a class
25
+ */
26
+ function getControllerMetadata(target) {
27
+ return controllerRegistry.get(target);
28
+ }
29
+ /**
30
+ * Set controller metadata for a class
31
+ */
32
+ function setControllerMetadata(target, metadata) {
33
+ controllerRegistry.set(target, metadata);
34
+ }
35
+ /**
36
+ * Check if a class is decorated with @JobsController
37
+ */
38
+ function isJobsController(target) {
39
+ return controllerRegistry.has(target);
40
+ }
41
+ //# sourceMappingURL=metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../../src/decorators/metadata.ts"],"names":[],"mappings":";;AAmDA,sEAOC;AAKD,sDAEC;AAKD,sDAEC;AAKD,4CAEC;AArCD;;;GAGG;AACH,MAAM,kBAAkB,GAAG,IAAI,OAAO,EAAmC,CAAC;AAE1E;;GAEG;AACH,SAAgB,6BAA6B,CAAC,MAAmB;IAChE,IAAI,QAAQ,GAAG,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACf,QAAQ,GAAG,EAAE,IAAI,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC;QAC/B,kBAAkB,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,QAAQ,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,SAAgB,qBAAqB,CAAC,MAAmB;IACxD,OAAO,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACvC,CAAC;AAED;;GAEG;AACH,SAAgB,qBAAqB,CAAC,MAAmB,EAAE,QAA4B;IACtF,kBAAkB,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AAC1C,CAAC;AAED;;GAEG;AACH,SAAgB,gBAAgB,CAAC,MAAmB;IACnD,OAAO,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AACvC,CAAC"}
@@ -0,0 +1,52 @@
1
+ import type { Agenda } from '../index.js';
2
+ import { type JobMetadata } from './metadata.js';
3
+ /**
4
+ * Error thrown when attempting to register an invalid jobs controller
5
+ */
6
+ export declare class JobsRegistrationError extends Error {
7
+ constructor(message: string);
8
+ }
9
+ /**
10
+ * Register job handlers from decorated class instances with an Agenda instance.
11
+ *
12
+ * This function reads the metadata from classes decorated with `@JobsController`
13
+ * and registers their methods as job handlers.
14
+ *
15
+ * @param agenda - The Agenda instance to register jobs with
16
+ * @param instances - Array of instantiated job controller classes
17
+ * @throws {JobsRegistrationError} If a class is not decorated with @JobsController
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * import { Agenda, registerJobs } from 'agenda';
22
+ * import { MongoBackend } from '@quave/agenda-mongodb';
23
+ * import { EmailJobs } from './jobs/email';
24
+ * import { ReportJobs } from './jobs/reports';
25
+ *
26
+ * const agenda = new Agenda({
27
+ * backend: new MongoBackend({ address: 'mongodb://localhost/agenda' })
28
+ * });
29
+ *
30
+ * // Create instances (can inject dependencies via constructor)
31
+ * const emailJobs = new EmailJobs(emailService);
32
+ * const reportJobs = new ReportJobs(reportService);
33
+ *
34
+ * // Register all job handlers
35
+ * registerJobs(agenda, [emailJobs, reportJobs]);
36
+ *
37
+ * await agenda.start();
38
+ * ```
39
+ */
40
+ export declare function registerJobs(agenda: Agenda, instances: object[]): void;
41
+ /**
42
+ * Get information about registered jobs from decorated classes.
43
+ * Useful for debugging and introspection.
44
+ *
45
+ * @param instances - Array of job controller instances
46
+ * @returns Array of job registration info
47
+ */
48
+ export declare function getRegisteredJobsInfo(instances: object[]): Array<{
49
+ className: string;
50
+ namespace?: string;
51
+ jobs: JobMetadata[];
52
+ }>;
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JobsRegistrationError = void 0;
4
+ exports.registerJobs = registerJobs;
5
+ exports.getRegisteredJobsInfo = getRegisteredJobsInfo;
6
+ const metadata_js_1 = require("./metadata.js");
7
+ /**
8
+ * Error thrown when attempting to register an invalid jobs controller
9
+ */
10
+ class JobsRegistrationError extends Error {
11
+ constructor(message) {
12
+ super(message);
13
+ this.name = 'JobsRegistrationError';
14
+ }
15
+ }
16
+ exports.JobsRegistrationError = JobsRegistrationError;
17
+ /**
18
+ * Register job handlers from decorated class instances with an Agenda instance.
19
+ *
20
+ * This function reads the metadata from classes decorated with `@JobsController`
21
+ * and registers their methods as job handlers.
22
+ *
23
+ * @param agenda - The Agenda instance to register jobs with
24
+ * @param instances - Array of instantiated job controller classes
25
+ * @throws {JobsRegistrationError} If a class is not decorated with @JobsController
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * import { Agenda, registerJobs } from 'agenda';
30
+ * import { MongoBackend } from '@quave/agenda-mongodb';
31
+ * import { EmailJobs } from './jobs/email';
32
+ * import { ReportJobs } from './jobs/reports';
33
+ *
34
+ * const agenda = new Agenda({
35
+ * backend: new MongoBackend({ address: 'mongodb://localhost/agenda' })
36
+ * });
37
+ *
38
+ * // Create instances (can inject dependencies via constructor)
39
+ * const emailJobs = new EmailJobs(emailService);
40
+ * const reportJobs = new ReportJobs(reportService);
41
+ *
42
+ * // Register all job handlers
43
+ * registerJobs(agenda, [emailJobs, reportJobs]);
44
+ *
45
+ * await agenda.start();
46
+ * ```
47
+ */
48
+ function registerJobs(agenda, instances) {
49
+ const pendingEveryJobs = [];
50
+ for (const instance of instances) {
51
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- instance.constructor is typed as Function
52
+ const constructor = instance.constructor;
53
+ // Validate that the class is decorated
54
+ if (!(0, metadata_js_1.isJobsController)(constructor)) {
55
+ throw new JobsRegistrationError(`Class "${constructor.name}" is not decorated with @JobsController. ` +
56
+ 'Make sure to add @JobsController() decorator to your class.');
57
+ }
58
+ const metadata = (0, metadata_js_1.getControllerMetadata)(constructor);
59
+ if (!metadata) {
60
+ continue;
61
+ }
62
+ registerJobsFromMetadata(agenda, instance, metadata, pendingEveryJobs);
63
+ }
64
+ // Schedule @Every jobs after agenda starts
65
+ if (pendingEveryJobs.length > 0) {
66
+ scheduleEveryJobsOnReady(agenda, pendingEveryJobs);
67
+ }
68
+ }
69
+ /**
70
+ * Register jobs from a single controller's metadata
71
+ */
72
+ function registerJobsFromMetadata(agenda, instance, metadata, pendingEveryJobs) {
73
+ const namespace = metadata.namespace;
74
+ for (const [methodName, jobMeta] of metadata.jobs) {
75
+ const jobName = buildJobName(namespace, jobMeta.options.name || methodName);
76
+ // Bind the method to the instance
77
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Dynamic method access requires any
78
+ const handler = instance[methodName].bind(instance);
79
+ // Create an async wrapper that matches Agenda's expected signature
80
+ const wrappedHandler = async (job) => {
81
+ await handler(job);
82
+ };
83
+ // Register the job definition with Agenda
84
+ agenda.define(jobName, wrappedHandler, {
85
+ concurrency: jobMeta.options.concurrency,
86
+ lockLifetime: jobMeta.options.lockLifetime,
87
+ lockLimit: jobMeta.options.lockLimit,
88
+ priority: jobMeta.options.priority
89
+ });
90
+ // Queue @Every jobs for scheduling after start
91
+ if (jobMeta.type === 'every' && jobMeta.interval !== undefined) {
92
+ pendingEveryJobs.push({
93
+ jobName,
94
+ interval: jobMeta.interval,
95
+ options: jobMeta.options
96
+ });
97
+ }
98
+ }
99
+ }
100
+ /**
101
+ * Build the full job name with optional namespace prefix
102
+ */
103
+ function buildJobName(namespace, name) {
104
+ return namespace ? `${namespace}.${name}` : name;
105
+ }
106
+ /**
107
+ * Schedule @Every jobs when Agenda emits the 'ready' event
108
+ */
109
+ function scheduleEveryJobsOnReady(agenda, pendingJobs) {
110
+ const scheduleJobs = async () => {
111
+ for (const pending of pendingJobs) {
112
+ await agenda.every(pending.interval, pending.jobName, undefined, {
113
+ timezone: pending.options.timezone,
114
+ skipImmediate: pending.options.skipImmediate
115
+ });
116
+ }
117
+ };
118
+ // The ready promise settles once whether the backend already connected
119
+ // or connects later, unlike a 'ready' listener which misses past events.
120
+ agenda.ready
121
+ .then(() => scheduleJobs())
122
+ .catch(err => {
123
+ agenda.emit('error', err);
124
+ });
125
+ }
126
+ /**
127
+ * Get information about registered jobs from decorated classes.
128
+ * Useful for debugging and introspection.
129
+ *
130
+ * @param instances - Array of job controller instances
131
+ * @returns Array of job registration info
132
+ */
133
+ function getRegisteredJobsInfo(instances) {
134
+ return instances.map(instance => {
135
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- instance.constructor is typed as Function
136
+ const constructor = instance.constructor;
137
+ const metadata = (0, metadata_js_1.getControllerMetadata)(constructor);
138
+ return {
139
+ className: constructor.name,
140
+ namespace: metadata?.namespace,
141
+ jobs: metadata ? Array.from(metadata.jobs.values()) : []
142
+ };
143
+ });
144
+ }
145
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../../../src/decorators/register.ts"],"names":[],"mappings":"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"}