@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,167 @@
1
+ /**
2
+ * Backoff strategy utilities for job retry logic
3
+ */
4
+ /**
5
+ * Apply jitter to a delay value
6
+ * @param delay - Base delay in milliseconds
7
+ * @param jitter - Jitter factor (0-1), where 0 means no jitter and 1 means up to ±100%
8
+ * @returns Delay with jitter applied
9
+ */
10
+ function applyJitter(delay, jitter) {
11
+ if (jitter <= 0)
12
+ return delay;
13
+ // Random value between -jitter and +jitter
14
+ const jitterAmount = delay * jitter * (Math.random() * 2 - 1);
15
+ return Math.max(0, Math.round(delay + jitterAmount));
16
+ }
17
+ /**
18
+ * Constant backoff - same delay between each retry
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * agenda.define('myJob', handler, {
23
+ * backoff: constant({ delay: 5000, maxRetries: 5 })
24
+ * });
25
+ * // Retries at: 5s, 5s, 5s, 5s, 5s
26
+ * ```
27
+ */
28
+ export function constant(options = {}) {
29
+ const { delay = 1000, maxDelay = Infinity, maxRetries = 3, jitter = 0 } = options;
30
+ return (context) => {
31
+ if (context.attempt > maxRetries) {
32
+ return null;
33
+ }
34
+ const baseDelay = Math.min(delay, maxDelay);
35
+ return applyJitter(baseDelay, jitter);
36
+ };
37
+ }
38
+ /**
39
+ * Linear backoff - delay increases by a fixed amount each retry
40
+ *
41
+ * @example
42
+ * ```ts
43
+ * agenda.define('myJob', handler, {
44
+ * backoff: linear({ delay: 1000, increment: 2000, maxRetries: 4 })
45
+ * });
46
+ * // Retries at: 1s, 3s, 5s, 7s
47
+ * ```
48
+ */
49
+ export function linear(options = {}) {
50
+ const { delay = 1000, increment = delay, maxDelay = Infinity, maxRetries = 3, jitter = 0 } = options;
51
+ return (context) => {
52
+ if (context.attempt > maxRetries) {
53
+ return null;
54
+ }
55
+ const baseDelay = delay + increment * (context.attempt - 1);
56
+ const cappedDelay = Math.min(baseDelay, maxDelay);
57
+ return applyJitter(cappedDelay, jitter);
58
+ };
59
+ }
60
+ /**
61
+ * Exponential backoff - delay multiplies by a factor each retry
62
+ *
63
+ * @example
64
+ * ```ts
65
+ * agenda.define('myJob', handler, {
66
+ * backoff: exponential({ delay: 1000, factor: 2, maxRetries: 5 })
67
+ * });
68
+ * // Retries at: 1s, 2s, 4s, 8s, 16s
69
+ *
70
+ * // With jitter to prevent thundering herd:
71
+ * agenda.define('myJob', handler, {
72
+ * backoff: exponential({ delay: 1000, factor: 2, maxRetries: 5, jitter: 0.2 })
73
+ * });
74
+ * ```
75
+ */
76
+ export function exponential(options = {}) {
77
+ const { delay = 1000, factor = 2, maxDelay = Infinity, maxRetries = 3, jitter = 0 } = options;
78
+ return (context) => {
79
+ if (context.attempt > maxRetries) {
80
+ return null;
81
+ }
82
+ const baseDelay = delay * Math.pow(factor, context.attempt - 1);
83
+ const cappedDelay = Math.min(baseDelay, maxDelay);
84
+ return applyJitter(cappedDelay, jitter);
85
+ };
86
+ }
87
+ /**
88
+ * Combine multiple strategies - tries each in sequence until one returns non-null
89
+ * Useful for implementing complex retry logic
90
+ *
91
+ * @example
92
+ * ```ts
93
+ * // Retry quickly at first, then back off
94
+ * agenda.define('myJob', handler, {
95
+ * backoff: combine(
96
+ * // First 2 retries: immediate (100ms)
97
+ * (ctx) => ctx.attempt <= 2 ? 100 : null,
98
+ * // Then exponential backoff for 3 more attempts
99
+ * exponential({ delay: 1000, maxRetries: 3 })
100
+ * )
101
+ * });
102
+ * ```
103
+ */
104
+ export function combine(...strategies) {
105
+ return (context) => {
106
+ for (const strategy of strategies) {
107
+ const result = strategy(context);
108
+ if (result !== null) {
109
+ return result;
110
+ }
111
+ }
112
+ return null;
113
+ };
114
+ }
115
+ /**
116
+ * Conditional backoff - only retry if condition is met
117
+ *
118
+ * @example
119
+ * ```ts
120
+ * // Only retry on specific errors
121
+ * agenda.define('myJob', handler, {
122
+ * backoff: when(
123
+ * (ctx) => ctx.error.message.includes('timeout'),
124
+ * exponential({ delay: 1000, maxRetries: 3 })
125
+ * )
126
+ * });
127
+ * ```
128
+ */
129
+ export function when(condition, strategy) {
130
+ return (context) => {
131
+ if (!condition(context)) {
132
+ return null;
133
+ }
134
+ return strategy(context);
135
+ };
136
+ }
137
+ /**
138
+ * Pre-configured backoff strategies for common use cases
139
+ */
140
+ export const backoffStrategies = {
141
+ /** Constant 1s delay, 3 retries */
142
+ constant,
143
+ /** Linear increase starting at 1s, 3 retries */
144
+ linear,
145
+ /** Exponential with factor 2, starting at 1s, 3 retries */
146
+ exponential,
147
+ /** Combine multiple strategies */
148
+ combine,
149
+ /** Conditional retry */
150
+ when,
151
+ /**
152
+ * Aggressive retry - quick retries for transient failures
153
+ * 100ms, 200ms, 400ms (3 retries in ~700ms total)
154
+ */
155
+ aggressive: () => exponential({ delay: 100, factor: 2, maxRetries: 3 }),
156
+ /**
157
+ * Relaxed retry - gentle backoff for rate-limited APIs
158
+ * 5s, 15s, 45s, 135s (4 retries over ~3 minutes)
159
+ */
160
+ relaxed: () => exponential({ delay: 5000, factor: 3, maxRetries: 4, jitter: 0.1 }),
161
+ /**
162
+ * Standard retry - balanced approach
163
+ * 1s, 2s, 4s, 8s, 16s (5 retries over ~31 seconds)
164
+ */
165
+ standard: () => exponential({ delay: 1000, factor: 2, maxRetries: 5, jitter: 0.1 })
166
+ };
167
+ //# sourceMappingURL=backoff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backoff.js","sourceRoot":"","sources":["../../src/utils/backoff.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Check if a given date should be skipped based on the skip days configuration.
3
+ * @param date - The date to check
4
+ * @param skipDays - Array of days to skip (0 = Sunday, 1 = Monday, ..., 6 = Saturday)
5
+ * @param timezone - Optional timezone for the check
6
+ * @returns true if the day should be skipped
7
+ */
8
+ export declare function shouldSkipDay(date: Date, skipDays?: number[], timezone?: string): boolean;
9
+ /**
10
+ * Applies skip days constraint to a date, moving forward to the next valid day.
11
+ * Preserves the time of day from the original date.
12
+ * @param date - The original date
13
+ * @param skipDays - Array of days to skip (0 = Sunday, 1 = Monday, ..., 6 = Saturday)
14
+ * @param timezone - Optional timezone
15
+ * @returns The adjusted date on a valid day, or null if no valid day found
16
+ */
17
+ export declare function applySkipDays(date: Date, skipDays?: number[], timezone?: string): Date | null;
18
+ /**
19
+ * Applies date range constraints to a nextRunAt date.
20
+ * - If nextRunAt is before startDate, returns startDate
21
+ * - If nextRunAt is after endDate, returns null (job should not run)
22
+ * @param nextRunAt - The computed next run time
23
+ * @param startDate - Optional start date constraint
24
+ * @param endDate - Optional end date constraint
25
+ * @returns The adjusted date, or null if outside valid range
26
+ */
27
+ export declare function applyDateRangeConstraints(nextRunAt: Date, startDate?: Date, endDate?: Date): Date | null;
28
+ /**
29
+ * Apply all date constraints (date range and skip days) to a computed nextRunAt.
30
+ * This is the main function to use when computing nextRunAt.
31
+ * @param nextRunAt - The base computed next run time
32
+ * @param options - Constraint options
33
+ * @returns The adjusted date respecting all constraints, or null if invalid
34
+ */
35
+ export declare function applyAllDateConstraints(nextRunAt: Date, options: {
36
+ startDate?: Date;
37
+ endDate?: Date;
38
+ skipDays?: number[];
39
+ timezone?: string;
40
+ }): Date | null;
41
+ /**
42
+ * Check if a date is within the valid date range.
43
+ * @param date - The date to check
44
+ * @param startDate - Optional start date constraint
45
+ * @param endDate - Optional end date constraint
46
+ * @returns true if the date is within the valid range
47
+ */
48
+ export declare function isWithinDateRange(date: Date, startDate?: Date, endDate?: Date): boolean;
@@ -0,0 +1,117 @@
1
+ import { DateTime } from 'luxon';
2
+ import debug from 'debug';
3
+ const log = debug('agenda:dateConstraints');
4
+ /**
5
+ * Check if a given date should be skipped based on the skip days configuration.
6
+ * @param date - The date to check
7
+ * @param skipDays - Array of days to skip (0 = Sunday, 1 = Monday, ..., 6 = Saturday)
8
+ * @param timezone - Optional timezone for the check
9
+ * @returns true if the day should be skipped
10
+ */
11
+ export function shouldSkipDay(date, skipDays, timezone) {
12
+ if (!skipDays || skipDays.length === 0) {
13
+ return false;
14
+ }
15
+ const dt = timezone
16
+ ? DateTime.fromJSDate(date, { zone: timezone })
17
+ : DateTime.fromJSDate(date);
18
+ // Luxon weekday: 1 = Monday, 7 = Sunday
19
+ // Convert to JS weekday: 0 = Sunday, 1 = Monday, ..., 6 = Saturday
20
+ const jsWeekday = dt.weekday === 7 ? 0 : dt.weekday;
21
+ return skipDays.includes(jsWeekday);
22
+ }
23
+ /**
24
+ * Applies skip days constraint to a date, moving forward to the next valid day.
25
+ * Preserves the time of day from the original date.
26
+ * @param date - The original date
27
+ * @param skipDays - Array of days to skip (0 = Sunday, 1 = Monday, ..., 6 = Saturday)
28
+ * @param timezone - Optional timezone
29
+ * @returns The adjusted date on a valid day, or null if no valid day found
30
+ */
31
+ export function applySkipDays(date, skipDays, timezone) {
32
+ if (!skipDays || skipDays.length === 0) {
33
+ return date;
34
+ }
35
+ // Validate skip days - if all days are skipped, return null
36
+ if (skipDays.length >= 7) {
37
+ log('all days are marked as skip days, returning null');
38
+ return null;
39
+ }
40
+ let dt = timezone
41
+ ? DateTime.fromJSDate(date, { zone: timezone })
42
+ : DateTime.fromJSDate(date);
43
+ // Luxon weekday: 1 = Monday, 7 = Sunday
44
+ // Convert to JS weekday: 0 = Sunday, 1 = Monday, ..., 6 = Saturday
45
+ const getJsWeekday = (luxonDt) => luxonDt.weekday === 7 ? 0 : luxonDt.weekday;
46
+ // Terminates within 6 steps: covering all 7 weekdays needs 7 distinct
47
+ // entries, which the length >= 7 guard above already rejected.
48
+ while (skipDays.includes(getJsWeekday(dt))) {
49
+ dt = dt.plus({ days: 1 });
50
+ log('skipping day, moved to %s', dt.toISO());
51
+ }
52
+ return dt.toJSDate();
53
+ }
54
+ /**
55
+ * Applies date range constraints to a nextRunAt date.
56
+ * - If nextRunAt is before startDate, returns startDate
57
+ * - If nextRunAt is after endDate, returns null (job should not run)
58
+ * @param nextRunAt - The computed next run time
59
+ * @param startDate - Optional start date constraint
60
+ * @param endDate - Optional end date constraint
61
+ * @returns The adjusted date, or null if outside valid range
62
+ */
63
+ export function applyDateRangeConstraints(nextRunAt, startDate, endDate) {
64
+ let result = nextRunAt;
65
+ // If before start date, move to start date
66
+ if (startDate && result < startDate) {
67
+ log('nextRunAt %s is before startDate %s, adjusting', result.toISOString(), startDate.toISOString());
68
+ result = new Date(startDate);
69
+ }
70
+ // If after end date, return null (job should stop)
71
+ if (endDate && result > endDate) {
72
+ log('nextRunAt %s is after endDate %s, returning null', result.toISOString(), endDate.toISOString());
73
+ return null;
74
+ }
75
+ return result;
76
+ }
77
+ /**
78
+ * Apply all date constraints (date range and skip days) to a computed nextRunAt.
79
+ * This is the main function to use when computing nextRunAt.
80
+ * @param nextRunAt - The base computed next run time
81
+ * @param options - Constraint options
82
+ * @returns The adjusted date respecting all constraints, or null if invalid
83
+ */
84
+ export function applyAllDateConstraints(nextRunAt, options) {
85
+ const { startDate, endDate, skipDays, timezone } = options;
86
+ // Step 1: If before startDate, move to startDate. The endDate check
87
+ // happens in step 3, after skip days may have moved the date.
88
+ let result = startDate && nextRunAt < startDate ? new Date(startDate) : nextRunAt;
89
+ // Step 2: Apply skip days
90
+ result = applySkipDays(result, skipDays, timezone);
91
+ if (!result) {
92
+ return null;
93
+ }
94
+ // Step 3: Check end date constraint again (skip days may have moved the date)
95
+ if (endDate && result > endDate) {
96
+ log('after skip days adjustment, date %s is after endDate %s', result.toISOString(), endDate.toISOString());
97
+ return null;
98
+ }
99
+ return result;
100
+ }
101
+ /**
102
+ * Check if a date is within the valid date range.
103
+ * @param date - The date to check
104
+ * @param startDate - Optional start date constraint
105
+ * @param endDate - Optional end date constraint
106
+ * @returns true if the date is within the valid range
107
+ */
108
+ export function isWithinDateRange(date, startDate, endDate) {
109
+ if (startDate && date < startDate) {
110
+ return false;
111
+ }
112
+ if (endDate && date > endDate) {
113
+ return false;
114
+ }
115
+ return true;
116
+ }
117
+ //# sourceMappingURL=dateConstraints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dateConstraints.js","sourceRoot":"","sources":["../../src/utils/dateConstraints.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function isValidDate(date: unknown): date is Date;
@@ -0,0 +1,5 @@
1
+ export function isValidDate(date) {
2
+ // An invalid date object returns NaN for getTime()
3
+ return date !== null && Number.isNaN(new Date(date).getTime()) === false;
4
+ }
5
+ //# sourceMappingURL=isValidDate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isValidDate.js","sourceRoot":"","sources":["../../src/utils/isValidDate.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW,CAAC,IAAa;IACxC,mDAAmD;IACnD,OAAO,IAAI,KAAK,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,IAAc,CAAC,CAAC,OAAO,EAAE,CAAC,KAAK,KAAK,CAAC;AACpF,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { JobParameters } from '../types/JobParameters.js';
2
+ export declare function isValidHumanInterval(value: unknown): value is string;
3
+ /**
4
+ * Internal method that computes the interval
5
+ */
6
+ export declare const computeFromInterval: (attrs: JobParameters<unknown>) => Date | null;
7
+ /**
8
+ * Internal method to compute next run time from the repeat string
9
+ */
10
+ export declare function computeFromRepeatAt(attrs: JobParameters<unknown>): Date | null;
@@ -0,0 +1,110 @@
1
+ import { DateTime } from 'luxon';
2
+ import date from 'date.js';
3
+ import debug from 'debug';
4
+ import { CronExpressionParser } from 'cron-parser';
5
+ import humanInterval from 'human-interval';
6
+ import { isValidDate } from './isValidDate.js';
7
+ import { applyAllDateConstraints } from './dateConstraints.js';
8
+ const log = debug('agenda:nextRunAt');
9
+ const dateForTimezone = (timezoneDate, timezone) => DateTime.fromJSDate(timezoneDate, { zone: timezone });
10
+ export function isValidHumanInterval(value) {
11
+ const transformedValue = humanInterval(value);
12
+ return typeof transformedValue === 'number' && Number.isNaN(transformedValue) === false;
13
+ }
14
+ /**
15
+ * Internal method that computes the interval
16
+ */
17
+ export const computeFromInterval = (attrs) => {
18
+ const previousNextRunAt = attrs.nextRunAt || new Date();
19
+ log('[%s:%s] computing next run via interval [%s]', attrs.name, attrs._id, attrs.repeatInterval);
20
+ const lastRun = dateForTimezone(attrs.lastRunAt || new Date(), attrs.repeatTimezone);
21
+ const cronOptions = {
22
+ currentDate: lastRun.toJSDate(),
23
+ tz: attrs.repeatTimezone
24
+ };
25
+ let nextRunAt = null;
26
+ let error;
27
+ if (typeof attrs.repeatInterval === 'string') {
28
+ try {
29
+ let cronTime = CronExpressionParser.parse(attrs.repeatInterval, cronOptions);
30
+ let nextDate = cronTime.next().toDate();
31
+ if (nextDate.valueOf() === lastRun.valueOf() ||
32
+ nextDate.valueOf() <= previousNextRunAt.valueOf()) {
33
+ // Handle cronTime giving back the same date for the next run time
34
+ cronOptions.currentDate = new Date(lastRun.valueOf() + 1000);
35
+ cronTime = CronExpressionParser.parse(attrs.repeatInterval, cronOptions);
36
+ nextDate = cronTime.next().toDate();
37
+ }
38
+ nextRunAt = nextDate;
39
+ }
40
+ catch (err) {
41
+ error = err;
42
+ }
43
+ }
44
+ if (isValidHumanInterval(attrs.repeatInterval)) {
45
+ if (!attrs.lastRunAt) {
46
+ nextRunAt = new Date(lastRun.valueOf());
47
+ }
48
+ else {
49
+ const intervalValue = humanInterval(attrs.repeatInterval);
50
+ nextRunAt = new Date(lastRun.valueOf() + intervalValue);
51
+ }
52
+ }
53
+ if (!isValidDate(nextRunAt)) {
54
+ log('[%s:%s] failed to calculate nextRunAt due to invalid repeat interval', attrs.name, attrs._id);
55
+ throw new Error(`failed to calculate nextRunAt due to invalid repeat interval (${attrs.repeatInterval}): ${error || 'no readable human interval'}`);
56
+ }
57
+ // Apply date constraints (startDate, endDate, skipDays)
58
+ if (attrs.startDate || attrs.endDate || attrs.skipDays) {
59
+ nextRunAt = applyAllDateConstraints(nextRunAt, {
60
+ startDate: attrs.startDate,
61
+ endDate: attrs.endDate,
62
+ skipDays: attrs.skipDays,
63
+ timezone: attrs.repeatTimezone
64
+ });
65
+ if (nextRunAt === null) {
66
+ log('[%s:%s] nextRunAt is null after applying date constraints', attrs.name, attrs._id);
67
+ }
68
+ }
69
+ return nextRunAt;
70
+ };
71
+ /**
72
+ * Internal method to compute next run time from the repeat string
73
+ */
74
+ export function computeFromRepeatAt(attrs) {
75
+ const lastRun = attrs.lastRunAt || new Date();
76
+ const repeatAt = attrs.repeatAt;
77
+ if (!repeatAt) {
78
+ throw new Error('repeatAt is required');
79
+ }
80
+ const nextDate = date(repeatAt).valueOf();
81
+ // If you do not specify offset date for below test it will fail for ms
82
+ const offset = Date.now();
83
+ if (offset === date(repeatAt, new Date(offset)).valueOf()) {
84
+ log('[%s:%s] failed to calculate repeatAt due to invalid format', attrs.name, attrs._id);
85
+ throw new Error('failed to calculate repeatAt time due to invalid format');
86
+ }
87
+ let nextRunAt;
88
+ if (nextDate === lastRun.valueOf()) {
89
+ nextRunAt = date('tomorrow at ' + repeatAt);
90
+ }
91
+ else {
92
+ nextRunAt = date(repeatAt);
93
+ }
94
+ // Apply date constraints (startDate, endDate, skipDays)
95
+ if (attrs.startDate || attrs.endDate || attrs.skipDays) {
96
+ const constrainedDate = applyAllDateConstraints(nextRunAt, {
97
+ startDate: attrs.startDate,
98
+ endDate: attrs.endDate,
99
+ skipDays: attrs.skipDays,
100
+ timezone: attrs.repeatTimezone
101
+ });
102
+ if (constrainedDate === null) {
103
+ log('[%s:%s] nextRunAt is null after applying date constraints', attrs.name, attrs._id);
104
+ return null;
105
+ }
106
+ nextRunAt = constrainedDate;
107
+ }
108
+ return nextRunAt;
109
+ }
110
+ //# sourceMappingURL=nextRunAt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nextRunAt.js","sourceRoot":"","sources":["../../src/utils/nextRunAt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export type JobPriority = number | keyof typeof priorityMap;
2
+ declare const priorityMap: {
3
+ lowest: number;
4
+ low: number;
5
+ normal: number;
6
+ high: number;
7
+ highest: number;
8
+ };
9
+ /**
10
+ * Internal method to turn priority into a number
11
+ */
12
+ export declare function parsePriority(priority?: JobPriority): number;
13
+ export {};
@@ -0,0 +1,20 @@
1
+ const priorityMap = {
2
+ lowest: -20,
3
+ low: -10,
4
+ normal: 0,
5
+ high: 10,
6
+ highest: 20
7
+ };
8
+ /**
9
+ * Internal method to turn priority into a number
10
+ */
11
+ export function parsePriority(priority) {
12
+ if (typeof priority === 'number') {
13
+ return priority;
14
+ }
15
+ if (typeof priority === 'string' && priorityMap[priority]) {
16
+ return priorityMap[priority];
17
+ }
18
+ return priorityMap.normal;
19
+ }
20
+ //# sourceMappingURL=priority.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"priority.js","sourceRoot":"","sources":["../../src/utils/priority.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,GAAG;IACnB,MAAM,EAAE,CAAC,EAAE;IACX,GAAG,EAAE,CAAC,EAAE;IACR,MAAM,EAAE,CAAC;IACT,IAAI,EAAE,EAAE;IACR,OAAO,EAAE,EAAE;CACX,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,QAAsB;IACnD,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,QAAQ,CAAC;IACjB,CAAC;IAED,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3D,OAAO,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO,WAAW,CAAC,MAAM,CAAC;AAC3B,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function calculateProcessEvery(input?: number | string): number;
@@ -0,0 +1,7 @@
1
+ import humanInterval from 'human-interval';
2
+ export function calculateProcessEvery(input = 5000) {
3
+ if (typeof input === 'number')
4
+ return input;
5
+ return humanInterval(input) || 5000;
6
+ }
7
+ //# sourceMappingURL=processEvery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processEvery.js","sourceRoot":"","sources":["../../src/utils/processEvery.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,MAAM,gBAAgB,CAAC;AAE3C,MAAM,UAAU,qBAAqB,CAAC,QAAyB,IAAI;IAClE,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,OAAQ,aAAa,CAAC,KAAK,CAAY,IAAI,IAAI,CAAC;AACjD,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function getCallerFilePath(position?: number): string | undefined;
@@ -0,0 +1,18 @@
1
+ export function getCallerFilePath(position = 2) {
2
+ if (position >= Error.stackTraceLimit) {
3
+ throw new TypeError(`getCallerFile(position) requires position be less then Error.stackTraceLimit but position was: \`${position}\` and Error.stackTraceLimit was: \`${Error.stackTraceLimit}\``);
4
+ }
5
+ const oldPrepareStackTrace = Error.prepareStackTrace;
6
+ Error.prepareStackTrace = (_, stack) => stack;
7
+ const { stack } = new Error();
8
+ Error.prepareStackTrace = oldPrepareStackTrace;
9
+ if (stack !== null && typeof stack === 'object') {
10
+ // stack[0] holds this file
11
+ // stack[1] holds where this function was called
12
+ // stack[2] holds the file we're interested in
13
+ const callSite = stack[position];
14
+ return callSite?.getFileName() ?? undefined;
15
+ }
16
+ return undefined;
17
+ }
18
+ //# sourceMappingURL=stack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stack.js","sourceRoot":"","sources":["../../src/utils/stack.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,iBAAiB,CAAC,QAAQ,GAAG,CAAC;IAC7C,IAAI,QAAQ,IAAI,KAAK,CAAC,eAAe,EAAE,CAAC;QACvC,MAAM,IAAI,SAAS,CAClB,oGAAoG,QAAQ,uCAAuC,KAAK,CAAC,eAAe,IAAI,CAC5K,CAAC;IACH,CAAC;IAED,MAAM,oBAAoB,GAAG,KAAK,CAAC,iBAAiB,CAAC;IACrD,KAAK,CAAC,iBAAiB,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC;IAC9C,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,KAAK,EAAE,CAAC;IAC9B,KAAK,CAAC,iBAAiB,GAAG,oBAAoB,CAAC;IAE/C,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACjD,2BAA2B;QAC3B,gDAAgD;QAChD,8CAA8C;QAC9C,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAgC,CAAC;QAChE,OAAO,QAAQ,EAAE,WAAW,EAAE,IAAI,SAAS,CAAC;IAC7C,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Package version, reported by getRunningStats().
3
+ *
4
+ * Kept as a source constant (instead of importing package.json) so the
5
+ * emitted code stays free of import.meta and JSON import attributes —
6
+ * required for the CommonJS build and for old runtimes (Meteor 2.x runs
7
+ * Node 14). A unit test asserts it matches package.json.
8
+ */
9
+ export declare const agendaVersion = "1.0.0";
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Package version, reported by getRunningStats().
3
+ *
4
+ * Kept as a source constant (instead of importing package.json) so the
5
+ * emitted code stays free of import.meta and JSON import attributes —
6
+ * required for the CommonJS build and for old runtimes (Meteor 2.x runs
7
+ * Node 14). A unit test asserts it matches package.json.
8
+ */
9
+ export const agendaVersion = '1.0.0';
10
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,OAAO,CAAC"}