@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,175 @@
1
+ "use strict";
2
+ /**
3
+ * Backoff strategy utilities for job retry logic
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.backoffStrategies = void 0;
7
+ exports.constant = constant;
8
+ exports.linear = linear;
9
+ exports.exponential = exponential;
10
+ exports.combine = combine;
11
+ exports.when = when;
12
+ /**
13
+ * Apply jitter to a delay value
14
+ * @param delay - Base delay in milliseconds
15
+ * @param jitter - Jitter factor (0-1), where 0 means no jitter and 1 means up to ±100%
16
+ * @returns Delay with jitter applied
17
+ */
18
+ function applyJitter(delay, jitter) {
19
+ if (jitter <= 0)
20
+ return delay;
21
+ // Random value between -jitter and +jitter
22
+ const jitterAmount = delay * jitter * (Math.random() * 2 - 1);
23
+ return Math.max(0, Math.round(delay + jitterAmount));
24
+ }
25
+ /**
26
+ * Constant backoff - same delay between each retry
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * agenda.define('myJob', handler, {
31
+ * backoff: constant({ delay: 5000, maxRetries: 5 })
32
+ * });
33
+ * // Retries at: 5s, 5s, 5s, 5s, 5s
34
+ * ```
35
+ */
36
+ function constant(options = {}) {
37
+ const { delay = 1000, maxDelay = Infinity, maxRetries = 3, jitter = 0 } = options;
38
+ return (context) => {
39
+ if (context.attempt > maxRetries) {
40
+ return null;
41
+ }
42
+ const baseDelay = Math.min(delay, maxDelay);
43
+ return applyJitter(baseDelay, jitter);
44
+ };
45
+ }
46
+ /**
47
+ * Linear backoff - delay increases by a fixed amount each retry
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * agenda.define('myJob', handler, {
52
+ * backoff: linear({ delay: 1000, increment: 2000, maxRetries: 4 })
53
+ * });
54
+ * // Retries at: 1s, 3s, 5s, 7s
55
+ * ```
56
+ */
57
+ function linear(options = {}) {
58
+ const { delay = 1000, increment = delay, maxDelay = Infinity, maxRetries = 3, jitter = 0 } = options;
59
+ return (context) => {
60
+ if (context.attempt > maxRetries) {
61
+ return null;
62
+ }
63
+ const baseDelay = delay + increment * (context.attempt - 1);
64
+ const cappedDelay = Math.min(baseDelay, maxDelay);
65
+ return applyJitter(cappedDelay, jitter);
66
+ };
67
+ }
68
+ /**
69
+ * Exponential backoff - delay multiplies by a factor each retry
70
+ *
71
+ * @example
72
+ * ```ts
73
+ * agenda.define('myJob', handler, {
74
+ * backoff: exponential({ delay: 1000, factor: 2, maxRetries: 5 })
75
+ * });
76
+ * // Retries at: 1s, 2s, 4s, 8s, 16s
77
+ *
78
+ * // With jitter to prevent thundering herd:
79
+ * agenda.define('myJob', handler, {
80
+ * backoff: exponential({ delay: 1000, factor: 2, maxRetries: 5, jitter: 0.2 })
81
+ * });
82
+ * ```
83
+ */
84
+ function exponential(options = {}) {
85
+ const { delay = 1000, factor = 2, maxDelay = Infinity, maxRetries = 3, jitter = 0 } = options;
86
+ return (context) => {
87
+ if (context.attempt > maxRetries) {
88
+ return null;
89
+ }
90
+ const baseDelay = delay * Math.pow(factor, context.attempt - 1);
91
+ const cappedDelay = Math.min(baseDelay, maxDelay);
92
+ return applyJitter(cappedDelay, jitter);
93
+ };
94
+ }
95
+ /**
96
+ * Combine multiple strategies - tries each in sequence until one returns non-null
97
+ * Useful for implementing complex retry logic
98
+ *
99
+ * @example
100
+ * ```ts
101
+ * // Retry quickly at first, then back off
102
+ * agenda.define('myJob', handler, {
103
+ * backoff: combine(
104
+ * // First 2 retries: immediate (100ms)
105
+ * (ctx) => ctx.attempt <= 2 ? 100 : null,
106
+ * // Then exponential backoff for 3 more attempts
107
+ * exponential({ delay: 1000, maxRetries: 3 })
108
+ * )
109
+ * });
110
+ * ```
111
+ */
112
+ function combine(...strategies) {
113
+ return (context) => {
114
+ for (const strategy of strategies) {
115
+ const result = strategy(context);
116
+ if (result !== null) {
117
+ return result;
118
+ }
119
+ }
120
+ return null;
121
+ };
122
+ }
123
+ /**
124
+ * Conditional backoff - only retry if condition is met
125
+ *
126
+ * @example
127
+ * ```ts
128
+ * // Only retry on specific errors
129
+ * agenda.define('myJob', handler, {
130
+ * backoff: when(
131
+ * (ctx) => ctx.error.message.includes('timeout'),
132
+ * exponential({ delay: 1000, maxRetries: 3 })
133
+ * )
134
+ * });
135
+ * ```
136
+ */
137
+ function when(condition, strategy) {
138
+ return (context) => {
139
+ if (!condition(context)) {
140
+ return null;
141
+ }
142
+ return strategy(context);
143
+ };
144
+ }
145
+ /**
146
+ * Pre-configured backoff strategies for common use cases
147
+ */
148
+ exports.backoffStrategies = {
149
+ /** Constant 1s delay, 3 retries */
150
+ constant,
151
+ /** Linear increase starting at 1s, 3 retries */
152
+ linear,
153
+ /** Exponential with factor 2, starting at 1s, 3 retries */
154
+ exponential,
155
+ /** Combine multiple strategies */
156
+ combine,
157
+ /** Conditional retry */
158
+ when,
159
+ /**
160
+ * Aggressive retry - quick retries for transient failures
161
+ * 100ms, 200ms, 400ms (3 retries in ~700ms total)
162
+ */
163
+ aggressive: () => exponential({ delay: 100, factor: 2, maxRetries: 3 }),
164
+ /**
165
+ * Relaxed retry - gentle backoff for rate-limited APIs
166
+ * 5s, 15s, 45s, 135s (4 retries over ~3 minutes)
167
+ */
168
+ relaxed: () => exponential({ delay: 5000, factor: 3, maxRetries: 4, jitter: 0.1 }),
169
+ /**
170
+ * Standard retry - balanced approach
171
+ * 1s, 2s, 4s, 8s, 16s (5 retries over ~31 seconds)
172
+ */
173
+ standard: () => exponential({ delay: 1000, factor: 2, maxRetries: 5, jitter: 0.1 })
174
+ };
175
+ //# 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,127 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.shouldSkipDay = shouldSkipDay;
7
+ exports.applySkipDays = applySkipDays;
8
+ exports.applyDateRangeConstraints = applyDateRangeConstraints;
9
+ exports.applyAllDateConstraints = applyAllDateConstraints;
10
+ exports.isWithinDateRange = isWithinDateRange;
11
+ const luxon_1 = require("luxon");
12
+ const debug_1 = __importDefault(require("debug"));
13
+ const log = (0, debug_1.default)('agenda:dateConstraints');
14
+ /**
15
+ * Check if a given date should be skipped based on the skip days configuration.
16
+ * @param date - The date to check
17
+ * @param skipDays - Array of days to skip (0 = Sunday, 1 = Monday, ..., 6 = Saturday)
18
+ * @param timezone - Optional timezone for the check
19
+ * @returns true if the day should be skipped
20
+ */
21
+ function shouldSkipDay(date, skipDays, timezone) {
22
+ if (!skipDays || skipDays.length === 0) {
23
+ return false;
24
+ }
25
+ const dt = timezone
26
+ ? luxon_1.DateTime.fromJSDate(date, { zone: timezone })
27
+ : luxon_1.DateTime.fromJSDate(date);
28
+ // Luxon weekday: 1 = Monday, 7 = Sunday
29
+ // Convert to JS weekday: 0 = Sunday, 1 = Monday, ..., 6 = Saturday
30
+ const jsWeekday = dt.weekday === 7 ? 0 : dt.weekday;
31
+ return skipDays.includes(jsWeekday);
32
+ }
33
+ /**
34
+ * Applies skip days constraint to a date, moving forward to the next valid day.
35
+ * Preserves the time of day from the original date.
36
+ * @param date - The original date
37
+ * @param skipDays - Array of days to skip (0 = Sunday, 1 = Monday, ..., 6 = Saturday)
38
+ * @param timezone - Optional timezone
39
+ * @returns The adjusted date on a valid day, or null if no valid day found
40
+ */
41
+ function applySkipDays(date, skipDays, timezone) {
42
+ if (!skipDays || skipDays.length === 0) {
43
+ return date;
44
+ }
45
+ // Validate skip days - if all days are skipped, return null
46
+ if (skipDays.length >= 7) {
47
+ log('all days are marked as skip days, returning null');
48
+ return null;
49
+ }
50
+ let dt = timezone
51
+ ? luxon_1.DateTime.fromJSDate(date, { zone: timezone })
52
+ : luxon_1.DateTime.fromJSDate(date);
53
+ // Luxon weekday: 1 = Monday, 7 = Sunday
54
+ // Convert to JS weekday: 0 = Sunday, 1 = Monday, ..., 6 = Saturday
55
+ const getJsWeekday = (luxonDt) => luxonDt.weekday === 7 ? 0 : luxonDt.weekday;
56
+ // Terminates within 6 steps: covering all 7 weekdays needs 7 distinct
57
+ // entries, which the length >= 7 guard above already rejected.
58
+ while (skipDays.includes(getJsWeekday(dt))) {
59
+ dt = dt.plus({ days: 1 });
60
+ log('skipping day, moved to %s', dt.toISO());
61
+ }
62
+ return dt.toJSDate();
63
+ }
64
+ /**
65
+ * Applies date range constraints to a nextRunAt date.
66
+ * - If nextRunAt is before startDate, returns startDate
67
+ * - If nextRunAt is after endDate, returns null (job should not run)
68
+ * @param nextRunAt - The computed next run time
69
+ * @param startDate - Optional start date constraint
70
+ * @param endDate - Optional end date constraint
71
+ * @returns The adjusted date, or null if outside valid range
72
+ */
73
+ function applyDateRangeConstraints(nextRunAt, startDate, endDate) {
74
+ let result = nextRunAt;
75
+ // If before start date, move to start date
76
+ if (startDate && result < startDate) {
77
+ log('nextRunAt %s is before startDate %s, adjusting', result.toISOString(), startDate.toISOString());
78
+ result = new Date(startDate);
79
+ }
80
+ // If after end date, return null (job should stop)
81
+ if (endDate && result > endDate) {
82
+ log('nextRunAt %s is after endDate %s, returning null', result.toISOString(), endDate.toISOString());
83
+ return null;
84
+ }
85
+ return result;
86
+ }
87
+ /**
88
+ * Apply all date constraints (date range and skip days) to a computed nextRunAt.
89
+ * This is the main function to use when computing nextRunAt.
90
+ * @param nextRunAt - The base computed next run time
91
+ * @param options - Constraint options
92
+ * @returns The adjusted date respecting all constraints, or null if invalid
93
+ */
94
+ function applyAllDateConstraints(nextRunAt, options) {
95
+ const { startDate, endDate, skipDays, timezone } = options;
96
+ // Step 1: If before startDate, move to startDate. The endDate check
97
+ // happens in step 3, after skip days may have moved the date.
98
+ let result = startDate && nextRunAt < startDate ? new Date(startDate) : nextRunAt;
99
+ // Step 2: Apply skip days
100
+ result = applySkipDays(result, skipDays, timezone);
101
+ if (!result) {
102
+ return null;
103
+ }
104
+ // Step 3: Check end date constraint again (skip days may have moved the date)
105
+ if (endDate && result > endDate) {
106
+ log('after skip days adjustment, date %s is after endDate %s', result.toISOString(), endDate.toISOString());
107
+ return null;
108
+ }
109
+ return result;
110
+ }
111
+ /**
112
+ * Check if a date is within the valid date range.
113
+ * @param date - The date to check
114
+ * @param startDate - Optional start date constraint
115
+ * @param endDate - Optional end date constraint
116
+ * @returns true if the date is within the valid range
117
+ */
118
+ function isWithinDateRange(date, startDate, endDate) {
119
+ if (startDate && date < startDate) {
120
+ return false;
121
+ }
122
+ if (endDate && date > endDate) {
123
+ return false;
124
+ }
125
+ return true;
126
+ }
127
+ //# 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,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isValidDate = isValidDate;
4
+ function isValidDate(date) {
5
+ // An invalid date object returns NaN for getTime()
6
+ return date !== null && Number.isNaN(new Date(date).getTime()) === false;
7
+ }
8
+ //# sourceMappingURL=isValidDate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isValidDate.js","sourceRoot":"","sources":["../../../src/utils/isValidDate.ts"],"names":[],"mappings":";;AAAA,kCAGC;AAHD,SAAgB,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,119 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.computeFromInterval = void 0;
7
+ exports.isValidHumanInterval = isValidHumanInterval;
8
+ exports.computeFromRepeatAt = computeFromRepeatAt;
9
+ const luxon_1 = require("luxon");
10
+ const date_js_1 = __importDefault(require("date.js"));
11
+ const debug_1 = __importDefault(require("debug"));
12
+ const cron_parser_1 = require("cron-parser");
13
+ const human_interval_1 = __importDefault(require("human-interval"));
14
+ const isValidDate_js_1 = require("./isValidDate.js");
15
+ const dateConstraints_js_1 = require("./dateConstraints.js");
16
+ const log = (0, debug_1.default)('agenda:nextRunAt');
17
+ const dateForTimezone = (timezoneDate, timezone) => luxon_1.DateTime.fromJSDate(timezoneDate, { zone: timezone });
18
+ function isValidHumanInterval(value) {
19
+ const transformedValue = (0, human_interval_1.default)(value);
20
+ return typeof transformedValue === 'number' && Number.isNaN(transformedValue) === false;
21
+ }
22
+ /**
23
+ * Internal method that computes the interval
24
+ */
25
+ const computeFromInterval = (attrs) => {
26
+ const previousNextRunAt = attrs.nextRunAt || new Date();
27
+ log('[%s:%s] computing next run via interval [%s]', attrs.name, attrs._id, attrs.repeatInterval);
28
+ const lastRun = dateForTimezone(attrs.lastRunAt || new Date(), attrs.repeatTimezone);
29
+ const cronOptions = {
30
+ currentDate: lastRun.toJSDate(),
31
+ tz: attrs.repeatTimezone
32
+ };
33
+ let nextRunAt = null;
34
+ let error;
35
+ if (typeof attrs.repeatInterval === 'string') {
36
+ try {
37
+ let cronTime = cron_parser_1.CronExpressionParser.parse(attrs.repeatInterval, cronOptions);
38
+ let nextDate = cronTime.next().toDate();
39
+ if (nextDate.valueOf() === lastRun.valueOf() ||
40
+ nextDate.valueOf() <= previousNextRunAt.valueOf()) {
41
+ // Handle cronTime giving back the same date for the next run time
42
+ cronOptions.currentDate = new Date(lastRun.valueOf() + 1000);
43
+ cronTime = cron_parser_1.CronExpressionParser.parse(attrs.repeatInterval, cronOptions);
44
+ nextDate = cronTime.next().toDate();
45
+ }
46
+ nextRunAt = nextDate;
47
+ }
48
+ catch (err) {
49
+ error = err;
50
+ }
51
+ }
52
+ if (isValidHumanInterval(attrs.repeatInterval)) {
53
+ if (!attrs.lastRunAt) {
54
+ nextRunAt = new Date(lastRun.valueOf());
55
+ }
56
+ else {
57
+ const intervalValue = (0, human_interval_1.default)(attrs.repeatInterval);
58
+ nextRunAt = new Date(lastRun.valueOf() + intervalValue);
59
+ }
60
+ }
61
+ if (!(0, isValidDate_js_1.isValidDate)(nextRunAt)) {
62
+ log('[%s:%s] failed to calculate nextRunAt due to invalid repeat interval', attrs.name, attrs._id);
63
+ throw new Error(`failed to calculate nextRunAt due to invalid repeat interval (${attrs.repeatInterval}): ${error || 'no readable human interval'}`);
64
+ }
65
+ // Apply date constraints (startDate, endDate, skipDays)
66
+ if (attrs.startDate || attrs.endDate || attrs.skipDays) {
67
+ nextRunAt = (0, dateConstraints_js_1.applyAllDateConstraints)(nextRunAt, {
68
+ startDate: attrs.startDate,
69
+ endDate: attrs.endDate,
70
+ skipDays: attrs.skipDays,
71
+ timezone: attrs.repeatTimezone
72
+ });
73
+ if (nextRunAt === null) {
74
+ log('[%s:%s] nextRunAt is null after applying date constraints', attrs.name, attrs._id);
75
+ }
76
+ }
77
+ return nextRunAt;
78
+ };
79
+ exports.computeFromInterval = computeFromInterval;
80
+ /**
81
+ * Internal method to compute next run time from the repeat string
82
+ */
83
+ function computeFromRepeatAt(attrs) {
84
+ const lastRun = attrs.lastRunAt || new Date();
85
+ const repeatAt = attrs.repeatAt;
86
+ if (!repeatAt) {
87
+ throw new Error('repeatAt is required');
88
+ }
89
+ const nextDate = (0, date_js_1.default)(repeatAt).valueOf();
90
+ // If you do not specify offset date for below test it will fail for ms
91
+ const offset = Date.now();
92
+ if (offset === (0, date_js_1.default)(repeatAt, new Date(offset)).valueOf()) {
93
+ log('[%s:%s] failed to calculate repeatAt due to invalid format', attrs.name, attrs._id);
94
+ throw new Error('failed to calculate repeatAt time due to invalid format');
95
+ }
96
+ let nextRunAt;
97
+ if (nextDate === lastRun.valueOf()) {
98
+ nextRunAt = (0, date_js_1.default)('tomorrow at ' + repeatAt);
99
+ }
100
+ else {
101
+ nextRunAt = (0, date_js_1.default)(repeatAt);
102
+ }
103
+ // Apply date constraints (startDate, endDate, skipDays)
104
+ if (attrs.startDate || attrs.endDate || attrs.skipDays) {
105
+ const constrainedDate = (0, dateConstraints_js_1.applyAllDateConstraints)(nextRunAt, {
106
+ startDate: attrs.startDate,
107
+ endDate: attrs.endDate,
108
+ skipDays: attrs.skipDays,
109
+ timezone: attrs.repeatTimezone
110
+ });
111
+ if (constrainedDate === null) {
112
+ log('[%s:%s] nextRunAt is null after applying date constraints', attrs.name, attrs._id);
113
+ return null;
114
+ }
115
+ nextRunAt = constrainedDate;
116
+ }
117
+ return nextRunAt;
118
+ }
119
+ //# sourceMappingURL=nextRunAt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nextRunAt.js","sourceRoot":"","sources":["../../../src/utils/nextRunAt.ts"],"names":[],"mappings":";;;;;;AAcA,oDAGC;AAiFD,kDA0CC;AA5ID,iCAAiC;AACjC,sDAA2B;AAC3B,kDAA0B;AAC1B,6CAAmD;AACnD,oEAA2C;AAC3C,qDAA+C;AAC/C,6DAA+D;AAG/D,MAAM,GAAG,GAAG,IAAA,eAAK,EAAC,kBAAkB,CAAC,CAAC;AAEtC,MAAM,eAAe,GAAG,CAAC,YAAkB,EAAE,QAAiB,EAAY,EAAE,CAC3E,gBAAQ,CAAC,UAAU,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;AAEvD,SAAgB,oBAAoB,CAAC,KAAc;IAClD,MAAM,gBAAgB,GAAG,IAAA,wBAAa,EAAC,KAAe,CAAC,CAAC;IACxD,OAAO,OAAO,gBAAgB,KAAK,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,KAAK,KAAK,CAAC;AACzF,CAAC;AAED;;GAEG;AACI,MAAM,mBAAmB,GAAG,CAAC,KAA6B,EAAe,EAAE;IACjF,MAAM,iBAAiB,GAAG,KAAK,CAAC,SAAS,IAAI,IAAI,IAAI,EAAE,CAAC;IACxD,GAAG,CAAC,8CAA8C,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;IAEjG,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,SAAS,IAAI,IAAI,IAAI,EAAE,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;IAErF,MAAM,WAAW,GAAG;QACnB,WAAW,EAAE,OAAO,CAAC,QAAQ,EAAE;QAC/B,EAAE,EAAE,KAAK,CAAC,cAAc;KACxB,CAAC;IAEF,IAAI,SAAS,GAAgB,IAAI,CAAC;IAElC,IAAI,KAAK,CAAC;IACV,IAAI,OAAO,KAAK,CAAC,cAAc,KAAK,QAAQ,EAAE,CAAC;QAC9C,IAAI,CAAC;YACJ,IAAI,QAAQ,GAAG,kCAAoB,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;YAC7E,IAAI,QAAQ,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC;YACxC,IACC,QAAQ,CAAC,OAAO,EAAE,KAAK,OAAO,CAAC,OAAO,EAAE;gBACxC,QAAQ,CAAC,OAAO,EAAE,IAAI,iBAAiB,CAAC,OAAO,EAAE,EAChD,CAAC;gBACF,kEAAkE;gBAClE,WAAW,CAAC,WAAW,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;gBAC7D,QAAQ,GAAG,kCAAoB,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;gBACzE,QAAQ,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC;YACrC,CAAC;YAED,SAAS,GAAG,QAAQ,CAAC;QACtB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,KAAK,GAAG,GAAG,CAAC;QACb,CAAC;IACF,CAAC;IAED,IAAI,oBAAoB,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC;QAChD,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;YACtB,SAAS,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QACzC,CAAC;aAAM,CAAC;YACP,MAAM,aAAa,GAAG,IAAA,wBAAa,EAAC,KAAK,CAAC,cAAc,CAAW,CAAC;YACpE,SAAS,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,aAAa,CAAC,CAAC;QACzD,CAAC;IACF,CAAC;IAED,IAAI,CAAC,IAAA,4BAAW,EAAC,SAAS,CAAC,EAAE,CAAC;QAC7B,GAAG,CACF,sEAAsE,EACtE,KAAK,CAAC,IAAI,EACV,KAAK,CAAC,GAAG,CACT,CAAC;QACF,MAAM,IAAI,KAAK,CACd,iEAAiE,KAAK,CAAC,cAAc,MACpF,KAAK,IAAI,4BACV,EAAE,CACF,CAAC;IACH,CAAC;IAED,wDAAwD;IACxD,IAAI,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACxD,SAAS,GAAG,IAAA,4CAAuB,EAAC,SAAS,EAAE;YAC9C,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,QAAQ,EAAE,KAAK,CAAC,cAAc;SAC9B,CAAC,CAAC;QAEH,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YACxB,GAAG,CAAC,2DAA2D,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QACzF,CAAC;IACF,CAAC;IAED,OAAO,SAAS,CAAC;AAClB,CAAC,CAAC;AAvEW,QAAA,mBAAmB,uBAuE9B;AAEF;;GAEG;AACH,SAAgB,mBAAmB,CAAC,KAA6B;IAChE,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,IAAI,IAAI,IAAI,EAAE,CAAC;IAC9C,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;IAChC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IACzC,CAAC;IAED,MAAM,QAAQ,GAAG,IAAA,iBAAI,EAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC;IAE1C,uEAAuE;IACvE,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE1B,IAAI,MAAM,KAAK,IAAA,iBAAI,EAAC,QAAQ,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;QAC3D,GAAG,CAAC,4DAA4D,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QACzF,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC5E,CAAC;IAED,IAAI,SAAe,CAAC;IACpB,IAAI,QAAQ,KAAK,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;QACpC,SAAS,GAAG,IAAA,iBAAI,EAAC,cAAc,GAAG,QAAQ,CAAC,CAAC;IAC7C,CAAC;SAAM,CAAC;QACP,SAAS,GAAG,IAAA,iBAAI,EAAC,QAAQ,CAAC,CAAC;IAC5B,CAAC;IAED,wDAAwD;IACxD,IAAI,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACxD,MAAM,eAAe,GAAG,IAAA,4CAAuB,EAAC,SAAS,EAAE;YAC1D,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,QAAQ,EAAE,KAAK,CAAC,cAAc;SAC9B,CAAC,CAAC;QAEH,IAAI,eAAe,KAAK,IAAI,EAAE,CAAC;YAC9B,GAAG,CAAC,2DAA2D,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;YACxF,OAAO,IAAI,CAAC;QACb,CAAC;QAED,SAAS,GAAG,eAAe,CAAC;IAC7B,CAAC;IAED,OAAO,SAAS,CAAC;AAClB,CAAC"}
@@ -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,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parsePriority = parsePriority;
4
+ const priorityMap = {
5
+ lowest: -20,
6
+ low: -10,
7
+ normal: 0,
8
+ high: 10,
9
+ highest: 20
10
+ };
11
+ /**
12
+ * Internal method to turn priority into a number
13
+ */
14
+ function parsePriority(priority) {
15
+ if (typeof priority === 'number') {
16
+ return priority;
17
+ }
18
+ if (typeof priority === 'string' && priorityMap[priority]) {
19
+ return priorityMap[priority];
20
+ }
21
+ return priorityMap.normal;
22
+ }
23
+ //# sourceMappingURL=priority.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"priority.js","sourceRoot":"","sources":["../../../src/utils/priority.ts"],"names":[],"mappings":";;AAaA,sCAUC;AArBD,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,SAAgB,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,13 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.calculateProcessEvery = calculateProcessEvery;
7
+ const human_interval_1 = __importDefault(require("human-interval"));
8
+ function calculateProcessEvery(input = 5000) {
9
+ if (typeof input === 'number')
10
+ return input;
11
+ return (0, human_interval_1.default)(input) || 5000;
12
+ }
13
+ //# sourceMappingURL=processEvery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processEvery.js","sourceRoot":"","sources":["../../../src/utils/processEvery.ts"],"names":[],"mappings":";;;;;AAEA,sDAGC;AALD,oEAA2C;AAE3C,SAAgB,qBAAqB,CAAC,QAAyB,IAAI;IAClE,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,OAAQ,IAAA,wBAAa,EAAC,KAAK,CAAY,IAAI,IAAI,CAAC;AACjD,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function getCallerFilePath(position?: number): string | undefined;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCallerFilePath = getCallerFilePath;
4
+ function getCallerFilePath(position = 2) {
5
+ if (position >= Error.stackTraceLimit) {
6
+ throw new TypeError(`getCallerFile(position) requires position be less then Error.stackTraceLimit but position was: \`${position}\` and Error.stackTraceLimit was: \`${Error.stackTraceLimit}\``);
7
+ }
8
+ const oldPrepareStackTrace = Error.prepareStackTrace;
9
+ Error.prepareStackTrace = (_, stack) => stack;
10
+ const { stack } = new Error();
11
+ Error.prepareStackTrace = oldPrepareStackTrace;
12
+ if (stack !== null && typeof stack === 'object') {
13
+ // stack[0] holds this file
14
+ // stack[1] holds where this function was called
15
+ // stack[2] holds the file we're interested in
16
+ const callSite = stack[position];
17
+ return callSite?.getFileName() ?? undefined;
18
+ }
19
+ return undefined;
20
+ }
21
+ //# sourceMappingURL=stack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stack.js","sourceRoot":"","sources":["../../../src/utils/stack.ts"],"names":[],"mappings":";;AAAA,8CAoBC;AApBD,SAAgB,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,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.agendaVersion = void 0;
4
+ /**
5
+ * Package version, reported by getRunningStats().
6
+ *
7
+ * Kept as a source constant (instead of importing package.json) so the
8
+ * emitted code stays free of import.meta and JSON import attributes —
9
+ * required for the CommonJS build and for old runtimes (Meteor 2.x runs
10
+ * Node 14). A unit test asserts it matches package.json.
11
+ */
12
+ exports.agendaVersion = '1.0.0';
13
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":";;;AAAA;;;;;;;GAOG;AACU,QAAA,aAAa,GAAG,OAAO,CAAC"}