@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.
- package/LICENSE.md +25 -0
- package/README.md +380 -0
- package/dist/Job.d.ts +190 -0
- package/dist/Job.js +689 -0
- package/dist/Job.js.map +1 -0
- package/dist/JobProcessingQueue.d.ts +47 -0
- package/dist/JobProcessingQueue.js +107 -0
- package/dist/JobProcessingQueue.js.map +1 -0
- package/dist/JobProcessor.d.ts +72 -0
- package/dist/JobProcessor.js +512 -0
- package/dist/JobProcessor.js.map +1 -0
- package/dist/backends/index.d.ts +18 -0
- package/dist/backends/index.js +20 -0
- package/dist/backends/index.js.map +1 -0
- package/dist/cjs/Job.d.ts +190 -0
- package/dist/cjs/Job.js +696 -0
- package/dist/cjs/Job.js.map +1 -0
- package/dist/cjs/JobProcessingQueue.d.ts +47 -0
- package/dist/cjs/JobProcessingQueue.js +111 -0
- package/dist/cjs/JobProcessingQueue.js.map +1 -0
- package/dist/cjs/JobProcessor.d.ts +72 -0
- package/dist/cjs/JobProcessor.js +519 -0
- package/dist/cjs/JobProcessor.js.map +1 -0
- package/dist/cjs/backends/index.d.ts +17 -0
- package/dist/cjs/backends/index.js +20 -0
- package/dist/cjs/backends/index.js.map +1 -0
- package/dist/cjs/decorators/Define.d.ts +33 -0
- package/dist/cjs/decorators/Define.js +47 -0
- package/dist/cjs/decorators/Define.js.map +1 -0
- package/dist/cjs/decorators/Every.d.ts +43 -0
- package/dist/cjs/decorators/Every.js +58 -0
- package/dist/cjs/decorators/Every.js.map +1 -0
- package/dist/cjs/decorators/JobsController.d.ts +43 -0
- package/dist/cjs/decorators/JobsController.js +40 -0
- package/dist/cjs/decorators/JobsController.js.map +1 -0
- package/dist/cjs/decorators/index.d.ts +41 -0
- package/dist/cjs/decorators/index.js +57 -0
- package/dist/cjs/decorators/index.js.map +1 -0
- package/dist/cjs/decorators/metadata.d.ts +50 -0
- package/dist/cjs/decorators/metadata.js +41 -0
- package/dist/cjs/decorators/metadata.js.map +1 -0
- package/dist/cjs/decorators/register.d.ts +52 -0
- package/dist/cjs/decorators/register.js +145 -0
- package/dist/cjs/decorators/register.js.map +1 -0
- package/dist/cjs/index.d.ts +498 -0
- package/dist/cjs/index.js +776 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/notifications/BaseNotificationChannel.d.ts +47 -0
- package/dist/cjs/notifications/BaseNotificationChannel.js +112 -0
- package/dist/cjs/notifications/BaseNotificationChannel.js.map +1 -0
- package/dist/cjs/notifications/InMemoryNotificationChannel.d.ts +13 -0
- package/dist/cjs/notifications/InMemoryNotificationChannel.js +37 -0
- package/dist/cjs/notifications/InMemoryNotificationChannel.js.map +1 -0
- package/dist/cjs/notifications/index.d.ts +2 -0
- package/dist/cjs/notifications/index.js +8 -0
- package/dist/cjs/notifications/index.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/types/AgendaBackend.d.ts +61 -0
- package/dist/cjs/types/AgendaBackend.js +3 -0
- package/dist/cjs/types/AgendaBackend.js.map +1 -0
- package/dist/cjs/types/AgendaConfig.d.ts +10 -0
- package/dist/cjs/types/AgendaConfig.js +3 -0
- package/dist/cjs/types/AgendaConfig.js.map +1 -0
- package/dist/cjs/types/AgendaStatus.d.ts +32 -0
- package/dist/cjs/types/AgendaStatus.js +3 -0
- package/dist/cjs/types/AgendaStatus.js.map +1 -0
- package/dist/cjs/types/DbOptions.d.ts +4 -0
- package/dist/cjs/types/DbOptions.js +3 -0
- package/dist/cjs/types/DbOptions.js.map +1 -0
- package/dist/cjs/types/DrainOptions.d.ts +37 -0
- package/dist/cjs/types/DrainOptions.js +3 -0
- package/dist/cjs/types/DrainOptions.js.map +1 -0
- package/dist/cjs/types/JobDefinition.d.ts +49 -0
- package/dist/cjs/types/JobDefinition.js +3 -0
- package/dist/cjs/types/JobDefinition.js.map +1 -0
- package/dist/cjs/types/JobLogger.d.ts +111 -0
- package/dist/cjs/types/JobLogger.js +3 -0
- package/dist/cjs/types/JobLogger.js.map +1 -0
- package/dist/cjs/types/JobParameters.d.ts +106 -0
- package/dist/cjs/types/JobParameters.js +21 -0
- package/dist/cjs/types/JobParameters.js.map +1 -0
- package/dist/cjs/types/JobQuery.d.ts +79 -0
- package/dist/cjs/types/JobQuery.js +36 -0
- package/dist/cjs/types/JobQuery.js.map +1 -0
- package/dist/cjs/types/JobRepository.d.ts +101 -0
- package/dist/cjs/types/JobRepository.js +3 -0
- package/dist/cjs/types/JobRepository.js.map +1 -0
- package/dist/cjs/types/NotificationChannel.d.ts +120 -0
- package/dist/cjs/types/NotificationChannel.js +3 -0
- package/dist/cjs/types/NotificationChannel.js.map +1 -0
- package/dist/cjs/utils/backoff.d.ts +152 -0
- package/dist/cjs/utils/backoff.js +175 -0
- package/dist/cjs/utils/backoff.js.map +1 -0
- package/dist/cjs/utils/dateConstraints.d.ts +48 -0
- package/dist/cjs/utils/dateConstraints.js +127 -0
- package/dist/cjs/utils/dateConstraints.js.map +1 -0
- package/dist/cjs/utils/isValidDate.d.ts +1 -0
- package/dist/cjs/utils/isValidDate.js +8 -0
- package/dist/cjs/utils/isValidDate.js.map +1 -0
- package/dist/cjs/utils/nextRunAt.d.ts +10 -0
- package/dist/cjs/utils/nextRunAt.js +119 -0
- package/dist/cjs/utils/nextRunAt.js.map +1 -0
- package/dist/cjs/utils/priority.d.ts +13 -0
- package/dist/cjs/utils/priority.js +23 -0
- package/dist/cjs/utils/priority.js.map +1 -0
- package/dist/cjs/utils/processEvery.d.ts +1 -0
- package/dist/cjs/utils/processEvery.js +13 -0
- package/dist/cjs/utils/processEvery.js.map +1 -0
- package/dist/cjs/utils/stack.d.ts +1 -0
- package/dist/cjs/utils/stack.js +21 -0
- package/dist/cjs/utils/stack.js.map +1 -0
- package/dist/cjs/version.d.ts +9 -0
- package/dist/cjs/version.js +13 -0
- package/dist/cjs/version.js.map +1 -0
- package/dist/decorators/Define.d.ts +33 -0
- package/dist/decorators/Define.js +44 -0
- package/dist/decorators/Define.js.map +1 -0
- package/dist/decorators/Every.d.ts +43 -0
- package/dist/decorators/Every.js +55 -0
- package/dist/decorators/Every.js.map +1 -0
- package/dist/decorators/JobsController.d.ts +43 -0
- package/dist/decorators/JobsController.js +37 -0
- package/dist/decorators/JobsController.js.map +1 -0
- package/dist/decorators/index.d.ts +41 -0
- package/dist/decorators/index.js +46 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/decorators/metadata.d.ts +50 -0
- package/dist/decorators/metadata.js +35 -0
- package/dist/decorators/metadata.js.map +1 -0
- package/dist/decorators/register.d.ts +52 -0
- package/dist/decorators/register.js +139 -0
- package/dist/decorators/register.js.map +1 -0
- package/dist/index.d.ts +498 -0
- package/dist/index.js +744 -0
- package/dist/index.js.map +1 -0
- package/dist/notifications/BaseNotificationChannel.d.ts +47 -0
- package/dist/notifications/BaseNotificationChannel.js +108 -0
- package/dist/notifications/BaseNotificationChannel.js.map +1 -0
- package/dist/notifications/InMemoryNotificationChannel.d.ts +13 -0
- package/dist/notifications/InMemoryNotificationChannel.js +33 -0
- package/dist/notifications/InMemoryNotificationChannel.js.map +1 -0
- package/dist/notifications/index.d.ts +2 -0
- package/dist/notifications/index.js +3 -0
- package/dist/notifications/index.js.map +1 -0
- package/dist/types/AgendaBackend.d.ts +61 -0
- package/dist/types/AgendaBackend.js +2 -0
- package/dist/types/AgendaBackend.js.map +1 -0
- package/dist/types/AgendaConfig.d.ts +10 -0
- package/dist/types/AgendaConfig.js +2 -0
- package/dist/types/AgendaConfig.js.map +1 -0
- package/dist/types/AgendaStatus.d.ts +32 -0
- package/dist/types/AgendaStatus.js +2 -0
- package/dist/types/AgendaStatus.js.map +1 -0
- package/dist/types/DbOptions.d.ts +4 -0
- package/dist/types/DbOptions.js +2 -0
- package/dist/types/DbOptions.js.map +1 -0
- package/dist/types/DrainOptions.d.ts +37 -0
- package/dist/types/DrainOptions.js +2 -0
- package/dist/types/DrainOptions.js.map +1 -0
- package/dist/types/JobDefinition.d.ts +49 -0
- package/dist/types/JobDefinition.js +2 -0
- package/dist/types/JobDefinition.js.map +1 -0
- package/dist/types/JobLogger.d.ts +111 -0
- package/dist/types/JobLogger.js +2 -0
- package/dist/types/JobLogger.js.map +1 -0
- package/dist/types/JobParameters.d.ts +106 -0
- package/dist/types/JobParameters.js +17 -0
- package/dist/types/JobParameters.js.map +1 -0
- package/dist/types/JobQuery.d.ts +79 -0
- package/dist/types/JobQuery.js +33 -0
- package/dist/types/JobQuery.js.map +1 -0
- package/dist/types/JobRepository.d.ts +101 -0
- package/dist/types/JobRepository.js +2 -0
- package/dist/types/JobRepository.js.map +1 -0
- package/dist/types/NotificationChannel.d.ts +120 -0
- package/dist/types/NotificationChannel.js +2 -0
- package/dist/types/NotificationChannel.js.map +1 -0
- package/dist/utils/backoff.d.ts +152 -0
- package/dist/utils/backoff.js +167 -0
- package/dist/utils/backoff.js.map +1 -0
- package/dist/utils/dateConstraints.d.ts +48 -0
- package/dist/utils/dateConstraints.js +117 -0
- package/dist/utils/dateConstraints.js.map +1 -0
- package/dist/utils/isValidDate.d.ts +1 -0
- package/dist/utils/isValidDate.js +5 -0
- package/dist/utils/isValidDate.js.map +1 -0
- package/dist/utils/nextRunAt.d.ts +10 -0
- package/dist/utils/nextRunAt.js +110 -0
- package/dist/utils/nextRunAt.js.map +1 -0
- package/dist/utils/priority.d.ts +13 -0
- package/dist/utils/priority.js +20 -0
- package/dist/utils/priority.js.map +1 -0
- package/dist/utils/processEvery.d.ts +1 -0
- package/dist/utils/processEvery.js +7 -0
- package/dist/utils/processEvery.js.map +1 -0
- package/dist/utils/stack.d.ts +1 -0
- package/dist/utils/stack.js +18 -0
- package/dist/utils/stack.js.map +1 -0
- package/dist/version.d.ts +9 -0
- package/dist/version.js +10 -0
- package/dist/version.js.map +1 -0
- package/package.json +79 -0
- package/test/fixtures/forkHelper.js +40 -0
- package/test/fixtures/someJobDefinition.ts +12 -0
- package/test/shared/agenda-test-suite.ts +1876 -0
- package/test/shared/backoff-test-suite.ts +408 -0
- package/test/shared/debounce-test-suite.ts +377 -0
- package/test/shared/full-test-suite.ts +161 -0
- package/test/shared/index.ts +50 -0
- package/test/shared/joblogger-test-suite.ts +305 -0
- package/test/shared/jobprocessor-test-suite.ts +266 -0
- package/test/shared/notification-channel-test-suite.ts +471 -0
- package/test/shared/removeoncomplete-test-suite.ts +228 -0
- package/test/shared/repository-test-suite.ts +708 -0
- package/test/shared/retry-test-suite.ts +174 -0
- package/test/shared/test-utils.ts +100 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retry test factory
|
|
3
|
+
*
|
|
4
|
+
* This file exports a test factory for job retry tests.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { retryTestSuite } from 'agenda/test/retry.test';
|
|
9
|
+
*
|
|
10
|
+
* retryTestSuite({
|
|
11
|
+
* name: 'Retry with MongoDB',
|
|
12
|
+
* createBackend: async () => new MongoBackend({ mongo: db }),
|
|
13
|
+
* cleanupBackend: async (backend) => await backend.disconnect(),
|
|
14
|
+
* clearJobs: async (backend) => await db.collection('agendaJobs').deleteMany({})
|
|
15
|
+
* });
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { describe, it, expect, beforeEach, afterEach, beforeAll, afterAll } from 'vitest';
|
|
20
|
+
import type { AgendaBackend } from '../../src/index.js';
|
|
21
|
+
import { Agenda } from '../../src/index.js';
|
|
22
|
+
|
|
23
|
+
export interface RetryTestConfig {
|
|
24
|
+
/** Name for the test suite */
|
|
25
|
+
name: string;
|
|
26
|
+
/** Factory to create a fresh backend instance */
|
|
27
|
+
createBackend: () => Promise<AgendaBackend>;
|
|
28
|
+
/** Cleanup function called after tests */
|
|
29
|
+
cleanupBackend: (backend: AgendaBackend) => Promise<void>;
|
|
30
|
+
/** Clear all jobs between tests */
|
|
31
|
+
clearJobs: (backend: AgendaBackend) => Promise<void>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Retry tests
|
|
36
|
+
*/
|
|
37
|
+
export function retryTestSuite(config: RetryTestConfig): void {
|
|
38
|
+
describe(`${config.name} - Retry`, () => {
|
|
39
|
+
let backend: AgendaBackend;
|
|
40
|
+
let agenda: Agenda;
|
|
41
|
+
|
|
42
|
+
beforeAll(async () => {
|
|
43
|
+
backend = await config.createBackend();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
afterAll(async () => {
|
|
47
|
+
await config.cleanupBackend(backend);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
beforeEach(async () => {
|
|
51
|
+
await config.clearJobs(backend);
|
|
52
|
+
agenda = new Agenda({
|
|
53
|
+
backend,
|
|
54
|
+
processEvery: 100
|
|
55
|
+
});
|
|
56
|
+
await agenda.ready;
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
afterEach(async () => {
|
|
60
|
+
if (agenda) {
|
|
61
|
+
await agenda.stop();
|
|
62
|
+
}
|
|
63
|
+
await config.clearJobs(backend);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('should retry a job - via attrs.nextRunAt', async () => {
|
|
67
|
+
let shouldFail = true;
|
|
68
|
+
|
|
69
|
+
agenda.define('a job', (_job, done) => {
|
|
70
|
+
if (shouldFail) {
|
|
71
|
+
shouldFail = false;
|
|
72
|
+
return done(new Error('test failure'));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
done();
|
|
76
|
+
return undefined;
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
agenda.on('fail:a job', (_err, job) => {
|
|
80
|
+
// Do nothing as this is expected to fail.
|
|
81
|
+
job.attrs.nextRunAt = new Date();
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
const successPromise = new Promise(resolve => {
|
|
85
|
+
agenda.on('success:a job', resolve);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
await agenda.now('a job');
|
|
89
|
+
|
|
90
|
+
await agenda.start();
|
|
91
|
+
await successPromise;
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('should retry a job - via schedule()', async () => {
|
|
95
|
+
let shouldFail = true;
|
|
96
|
+
|
|
97
|
+
agenda.define('a job', (_job, done) => {
|
|
98
|
+
if (shouldFail) {
|
|
99
|
+
shouldFail = false;
|
|
100
|
+
return done(new Error('test failure'));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
done();
|
|
104
|
+
return undefined;
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
agenda.on('fail:a job', (_err, job) => {
|
|
108
|
+
// Do nothing as this is expected to fail.
|
|
109
|
+
job.schedule('now').save();
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const successPromise = new Promise(resolve => {
|
|
113
|
+
agenda.on('success:a job', resolve);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
await agenda.now('a job');
|
|
117
|
+
|
|
118
|
+
await agenda.start();
|
|
119
|
+
await successPromise;
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('should track failCount on retry - via attrs.nextRunAt', async () => {
|
|
123
|
+
let attempts = 0;
|
|
124
|
+
|
|
125
|
+
agenda.define('failing-job', async () => {
|
|
126
|
+
attempts++;
|
|
127
|
+
if (attempts < 3) {
|
|
128
|
+
throw new Error(`Attempt ${attempts} failed`);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
agenda.on('fail:failing-job', (_err, job) => {
|
|
133
|
+
// Retry immediately
|
|
134
|
+
job.attrs.nextRunAt = new Date();
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
const successPromise = new Promise(resolve => {
|
|
138
|
+
agenda.on('success:failing-job', resolve);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
await agenda.now('failing-job');
|
|
142
|
+
await agenda.start();
|
|
143
|
+
await successPromise;
|
|
144
|
+
expect(attempts).toBe(3);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('should track failCount on retry - via schedule()', async () => {
|
|
148
|
+
let attempts = 0;
|
|
149
|
+
|
|
150
|
+
agenda.define('failing-job', async () => {
|
|
151
|
+
attempts++;
|
|
152
|
+
if (attempts < 3) {
|
|
153
|
+
throw new Error(`Attempt ${attempts} failed`);
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
agenda.on('fail:failing-job', (_err, job) => {
|
|
158
|
+
// Retry immediately
|
|
159
|
+
job.schedule('now').save();
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
const successPromise = new Promise(resolve => {
|
|
163
|
+
agenda.on('success:failing-job', resolve);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
await agenda.now('failing-job');
|
|
167
|
+
await agenda.start();
|
|
168
|
+
await successPromise;
|
|
169
|
+
|
|
170
|
+
expect(attempts).toBe(3);
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared test utilities for Agenda test suites
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { Agenda, AgendaEventName } from '../../src/index.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Promise-based delay utility
|
|
9
|
+
*/
|
|
10
|
+
export const delay = (ms: number): Promise<void> =>
|
|
11
|
+
new Promise(resolve => setTimeout(resolve, ms));
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Poll a predicate until it returns true or the timeout elapses.
|
|
15
|
+
* Resolves true as soon as the predicate holds, false on timeout.
|
|
16
|
+
*/
|
|
17
|
+
export async function waitFor(
|
|
18
|
+
predicate: () => boolean | Promise<boolean>,
|
|
19
|
+
timeoutMs: number = 5000,
|
|
20
|
+
intervalMs: number = 25
|
|
21
|
+
): Promise<boolean> {
|
|
22
|
+
const deadline = Date.now() + timeoutMs;
|
|
23
|
+
for (;;) {
|
|
24
|
+
if (await predicate()) {
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
if (Date.now() >= deadline) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
await delay(intervalMs);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Wait for a single event with timeout
|
|
36
|
+
*/
|
|
37
|
+
export function waitForEvent(
|
|
38
|
+
agenda: Agenda,
|
|
39
|
+
eventName: AgendaEventName,
|
|
40
|
+
timeoutMs: number = 5000
|
|
41
|
+
): Promise<unknown> {
|
|
42
|
+
return new Promise((resolve, reject) => {
|
|
43
|
+
const timeout = setTimeout(() => {
|
|
44
|
+
reject(new Error(`Timeout waiting for event: ${eventName}`));
|
|
45
|
+
}, timeoutMs);
|
|
46
|
+
|
|
47
|
+
agenda.once(eventName, (...args: unknown[]) => {
|
|
48
|
+
clearTimeout(timeout);
|
|
49
|
+
resolve(args[0]);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Schedule a job with agenda.now() and wait for an event (race-condition safe).
|
|
56
|
+
* Sets up the event listener BEFORE scheduling the job to avoid missing fast events.
|
|
57
|
+
*/
|
|
58
|
+
export async function runJobAndWait(
|
|
59
|
+
agenda: Agenda,
|
|
60
|
+
jobName: string,
|
|
61
|
+
eventName: AgendaEventName,
|
|
62
|
+
data?: Record<string, unknown>,
|
|
63
|
+
timeoutMs: number = 5000
|
|
64
|
+
): Promise<void> {
|
|
65
|
+
const eventPromise = waitForEvent(agenda, eventName, timeoutMs);
|
|
66
|
+
await agenda.now(jobName, data);
|
|
67
|
+
|
|
68
|
+
await eventPromise;
|
|
69
|
+
await new Promise(resolve => process.nextTick(resolve));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Wait for multiple occurrences of an event with timeout
|
|
74
|
+
*/
|
|
75
|
+
export function waitForEvents(
|
|
76
|
+
agenda: Agenda,
|
|
77
|
+
eventName: AgendaEventName,
|
|
78
|
+
count: number,
|
|
79
|
+
timeoutMs: number = 10000
|
|
80
|
+
): Promise<unknown[]> {
|
|
81
|
+
return new Promise((resolve, reject) => {
|
|
82
|
+
const results: unknown[] = [];
|
|
83
|
+
const timeout = setTimeout(() => {
|
|
84
|
+
reject(new Error(`Timeout waiting for ${count} ${eventName} events, got ${results.length}`));
|
|
85
|
+
}, timeoutMs);
|
|
86
|
+
|
|
87
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
88
|
+
const handler = (...args: any[]) => {
|
|
89
|
+
results.push(args[0]);
|
|
90
|
+
if (results.length >= count) {
|
|
91
|
+
clearTimeout(timeout);
|
|
92
|
+
agenda.off(eventName, handler);
|
|
93
|
+
resolve(results);
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
98
|
+
agenda.on(eventName as any, handler);
|
|
99
|
+
});
|
|
100
|
+
}
|