@morojs/moro 1.6.5 → 1.6.8
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/README.md +20 -4
- package/dist/core/auth/morojs-adapter.js +17 -14
- package/dist/core/auth/morojs-adapter.js.map +1 -1
- package/dist/core/config/config-sources.js +44 -0
- package/dist/core/config/config-sources.js.map +1 -1
- package/dist/core/database/adapters/drizzle.js +5 -5
- package/dist/core/database/adapters/drizzle.js.map +1 -1
- package/dist/core/database/adapters/mongodb.js +5 -1
- package/dist/core/database/adapters/mongodb.js.map +1 -1
- package/dist/core/database/adapters/mysql.js +5 -1
- package/dist/core/database/adapters/mysql.js.map +1 -1
- package/dist/core/database/adapters/postgresql.js +1 -1
- package/dist/core/database/adapters/postgresql.js.map +1 -1
- package/dist/core/database/adapters/redis.js +2 -2
- package/dist/core/database/adapters/redis.js.map +1 -1
- package/dist/core/database/adapters/sqlite.js +5 -1
- package/dist/core/database/adapters/sqlite.js.map +1 -1
- package/dist/core/docs/index.js.map +1 -1
- package/dist/core/docs/simple-docs.js +2 -1
- package/dist/core/docs/simple-docs.js.map +1 -1
- package/dist/core/docs/swagger-ui.js +1 -0
- package/dist/core/docs/swagger-ui.js.map +1 -1
- package/dist/core/docs/zod-to-openapi.js +4 -0
- package/dist/core/docs/zod-to-openapi.js.map +1 -1
- package/dist/core/events/event-bus.d.ts +1 -1
- package/dist/core/events/event-bus.js +8 -4
- package/dist/core/events/event-bus.js.map +1 -1
- package/dist/core/framework.d.ts +1 -1
- package/dist/core/framework.js +3 -1
- package/dist/core/framework.js.map +1 -1
- package/dist/core/graphql/adapter.d.ts +73 -0
- package/dist/core/graphql/adapter.js +2 -0
- package/dist/core/graphql/adapter.js.map +1 -0
- package/dist/core/graphql/adapters/graphql-js-adapter.d.ts +26 -0
- package/dist/core/graphql/adapters/graphql-js-adapter.js +229 -0
- package/dist/core/graphql/adapters/graphql-js-adapter.js.map +1 -0
- package/dist/core/graphql/core.d.ts +60 -0
- package/dist/core/graphql/core.js +165 -0
- package/dist/core/graphql/core.js.map +1 -0
- package/dist/core/graphql/index.d.ts +4 -0
- package/dist/core/graphql/index.js +4 -0
- package/dist/core/graphql/index.js.map +1 -0
- package/dist/core/graphql/loader.d.ts +9 -0
- package/dist/core/graphql/loader.js +32 -0
- package/dist/core/graphql/loader.js.map +1 -0
- package/dist/core/graphql/types.d.ts +211 -0
- package/dist/core/graphql/types.js +2 -0
- package/dist/core/graphql/types.js.map +1 -0
- package/dist/core/http/http-server.d.ts +7 -0
- package/dist/core/http/http-server.js +267 -123
- package/dist/core/http/http-server.js.map +1 -1
- package/dist/core/http/utils/uws-worker-clustering.d.ts +28 -0
- package/dist/core/http/utils/uws-worker-clustering.js +313 -0
- package/dist/core/http/utils/uws-worker-clustering.js.map +1 -0
- package/dist/core/http/uws-http-server.d.ts +7 -1
- package/dist/core/http/uws-http-server.js +272 -189
- package/dist/core/http/uws-http-server.js.map +1 -1
- package/dist/core/jobs/cron-parser.d.ts +62 -0
- package/dist/core/jobs/cron-parser.js +239 -0
- package/dist/core/jobs/cron-parser.js.map +1 -0
- package/dist/core/jobs/index.d.ts +12 -0
- package/dist/core/jobs/index.js +9 -0
- package/dist/core/jobs/index.js.map +1 -0
- package/dist/core/jobs/job-executor.d.ts +134 -0
- package/dist/core/jobs/job-executor.js +413 -0
- package/dist/core/jobs/job-executor.js.map +1 -0
- package/dist/core/jobs/job-scheduler.d.ts +214 -0
- package/dist/core/jobs/job-scheduler.js +551 -0
- package/dist/core/jobs/job-scheduler.js.map +1 -0
- package/dist/core/jobs/job-state-manager.d.ts +158 -0
- package/dist/core/jobs/job-state-manager.js +444 -0
- package/dist/core/jobs/job-state-manager.js.map +1 -0
- package/dist/core/jobs/leader-election.d.ts +124 -0
- package/dist/core/jobs/leader-election.js +481 -0
- package/dist/core/jobs/leader-election.js.map +1 -0
- package/dist/core/jobs/types.d.ts +151 -0
- package/dist/core/jobs/types.js +4 -0
- package/dist/core/jobs/types.js.map +1 -0
- package/dist/core/jobs/utils.d.ts +95 -0
- package/dist/core/jobs/utils.js +258 -0
- package/dist/core/jobs/utils.js.map +1 -0
- package/dist/core/logger/filters.js +2 -0
- package/dist/core/logger/filters.js.map +1 -1
- package/dist/core/logger/logger.d.ts +7 -5
- package/dist/core/logger/logger.js +68 -27
- package/dist/core/logger/logger.js.map +1 -1
- package/dist/core/logger/outputs.js +2 -0
- package/dist/core/logger/outputs.js.map +1 -1
- package/dist/core/middleware/built-in/auth/helpers.js +1 -1
- package/dist/core/middleware/built-in/auth/helpers.js.map +1 -1
- package/dist/core/middleware/built-in/auth/jwt-helpers.js +1 -1
- package/dist/core/middleware/built-in/auth/jwt-helpers.js.map +1 -1
- package/dist/core/middleware/built-in/auth/providers.js +1 -1
- package/dist/core/middleware/built-in/auth/providers.js.map +1 -1
- package/dist/core/middleware/built-in/cache/adapters/cache/file.js +3 -3
- package/dist/core/middleware/built-in/cache/adapters/cache/file.js.map +1 -1
- package/dist/core/middleware/built-in/cache/adapters/cache/memory.js +1 -0
- package/dist/core/middleware/built-in/cache/adapters/cache/memory.js.map +1 -1
- package/dist/core/middleware/built-in/cache/adapters/cache/redis.js +1 -1
- package/dist/core/middleware/built-in/cache/adapters/cache/redis.js.map +1 -1
- package/dist/core/middleware/built-in/cdn/adapters/cdn/azure.d.ts +8 -0
- package/dist/core/middleware/built-in/cdn/adapters/cdn/azure.js +100 -7
- package/dist/core/middleware/built-in/cdn/adapters/cdn/azure.js.map +1 -1
- package/dist/core/middleware/built-in/cdn/adapters/cdn/cloudflare.d.ts +6 -0
- package/dist/core/middleware/built-in/cdn/adapters/cdn/cloudflare.js +97 -13
- package/dist/core/middleware/built-in/cdn/adapters/cdn/cloudflare.js.map +1 -1
- package/dist/core/middleware/built-in/cdn/adapters/cdn/cloudfront.js +1 -1
- package/dist/core/middleware/built-in/cdn/adapters/cdn/cloudfront.js.map +1 -1
- package/dist/core/middleware/built-in/cookie/hook.d.ts +1 -1
- package/dist/core/middleware/built-in/cookie/hook.js +2 -2
- package/dist/core/middleware/built-in/cookie/hook.js.map +1 -1
- package/dist/core/middleware/built-in/csrf/core.js +1 -0
- package/dist/core/middleware/built-in/csrf/core.js.map +1 -1
- package/dist/core/middleware/built-in/graphql/core.d.ts +11 -0
- package/dist/core/middleware/built-in/graphql/core.js +24 -0
- package/dist/core/middleware/built-in/graphql/core.js.map +1 -0
- package/dist/core/middleware/built-in/graphql/helpers.d.ts +69 -0
- package/dist/core/middleware/built-in/graphql/helpers.js +187 -0
- package/dist/core/middleware/built-in/graphql/helpers.js.map +1 -0
- package/dist/core/middleware/built-in/graphql/hook.d.ts +7 -0
- package/dist/core/middleware/built-in/graphql/hook.js +78 -0
- package/dist/core/middleware/built-in/graphql/hook.js.map +1 -0
- package/dist/core/middleware/built-in/graphql/index.d.ts +5 -0
- package/dist/core/middleware/built-in/graphql/index.js +5 -0
- package/dist/core/middleware/built-in/graphql/index.js.map +1 -0
- package/dist/core/middleware/built-in/graphql/middleware.d.ts +7 -0
- package/dist/core/middleware/built-in/graphql/middleware.js +54 -0
- package/dist/core/middleware/built-in/graphql/middleware.js.map +1 -0
- package/dist/core/middleware/built-in/graphql/subscriptions.d.ts +20 -0
- package/dist/core/middleware/built-in/graphql/subscriptions.js +37 -0
- package/dist/core/middleware/built-in/graphql/subscriptions.js.map +1 -0
- package/dist/core/middleware/built-in/index.d.ts +2 -1
- package/dist/core/middleware/built-in/index.js +3 -0
- package/dist/core/middleware/built-in/index.js.map +1 -1
- package/dist/core/middleware/built-in/rate-limit/core.d.ts +5 -0
- package/dist/core/middleware/built-in/rate-limit/core.js +16 -8
- package/dist/core/middleware/built-in/rate-limit/core.js.map +1 -1
- package/dist/core/middleware/built-in/validation/core.js +42 -19
- package/dist/core/middleware/built-in/validation/core.js.map +1 -1
- package/dist/core/middleware/index.js +1 -0
- package/dist/core/middleware/index.js.map +1 -1
- package/dist/core/modules/auto-discovery.js +5 -4
- package/dist/core/modules/auto-discovery.js.map +1 -1
- package/dist/core/modules/modules.js.map +1 -1
- package/dist/core/networking/adapters/socketio-adapter.js +1 -1
- package/dist/core/networking/adapters/socketio-adapter.js.map +1 -1
- package/dist/core/networking/adapters/uws-adapter.js +7 -2
- package/dist/core/networking/adapters/uws-adapter.js.map +1 -1
- package/dist/core/networking/adapters/ws-adapter.js +5 -2
- package/dist/core/networking/adapters/ws-adapter.js.map +1 -1
- package/dist/core/networking/websocket-manager.js +2 -0
- package/dist/core/networking/websocket-manager.js.map +1 -1
- package/dist/core/pooling/object-pool-manager.d.ts +8 -2
- package/dist/core/pooling/object-pool-manager.js +38 -18
- package/dist/core/pooling/object-pool-manager.js.map +1 -1
- package/dist/core/routing/app-integration.d.ts +3 -3
- package/dist/core/routing/app-integration.js +1 -1
- package/dist/core/routing/app-integration.js.map +1 -1
- package/dist/core/routing/index.d.ts +1 -1
- package/dist/core/routing/index.js +1 -1
- package/dist/core/routing/index.js.map +1 -1
- package/dist/core/routing/path-matcher.d.ts +6 -0
- package/dist/core/routing/path-matcher.js +46 -7
- package/dist/core/routing/path-matcher.js.map +1 -1
- package/dist/core/routing/unified-router.d.ts +4 -0
- package/dist/core/routing/unified-router.js +104 -43
- package/dist/core/routing/unified-router.js.map +1 -1
- package/dist/core/runtime/base-adapter.js +3 -3
- package/dist/core/runtime/base-adapter.js.map +1 -1
- package/dist/core/runtime/cloudflare-workers-adapter.js +1 -1
- package/dist/core/runtime/cloudflare-workers-adapter.js.map +1 -1
- package/dist/core/runtime/node-adapter.d.ts +1 -1
- package/dist/core/runtime/node-adapter.js +7 -4
- package/dist/core/runtime/node-adapter.js.map +1 -1
- package/dist/core/runtime/vercel-edge-adapter.js +1 -0
- package/dist/core/runtime/vercel-edge-adapter.js.map +1 -1
- package/dist/core/utilities/circuit-breaker.d.ts +9 -2
- package/dist/core/utilities/circuit-breaker.js +32 -3
- package/dist/core/utilities/circuit-breaker.js.map +1 -1
- package/dist/core/utilities/container.js +6 -0
- package/dist/core/utilities/container.js.map +1 -1
- package/dist/core/utilities/hooks.d.ts +4 -0
- package/dist/core/utilities/hooks.js +134 -22
- package/dist/core/utilities/hooks.js.map +1 -1
- package/dist/core/validation/index.js +6 -1
- package/dist/core/validation/index.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/moro.d.ts +154 -1
- package/dist/moro.js +592 -16
- package/dist/moro.js.map +1 -1
- package/dist/types/config.d.ts +28 -0
- package/dist/types/core.d.ts +1 -0
- package/dist/types/events.d.ts +1 -1
- package/dist/types/events.js +1 -0
- package/dist/types/events.js.map +1 -1
- package/dist/types/logger.d.ts +1 -0
- package/dist/types/module.d.ts +2 -2
- package/package.json +21 -1
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export interface CronSchedule {
|
|
2
|
+
minutes: number[];
|
|
3
|
+
hours: number[];
|
|
4
|
+
daysOfMonth: number[];
|
|
5
|
+
months: number[];
|
|
6
|
+
daysOfWeek: number[];
|
|
7
|
+
}
|
|
8
|
+
export interface NextRunResult {
|
|
9
|
+
next: Date;
|
|
10
|
+
delay: number;
|
|
11
|
+
}
|
|
12
|
+
export declare class CronParser {
|
|
13
|
+
private schedule;
|
|
14
|
+
private timezone;
|
|
15
|
+
private originalExpression;
|
|
16
|
+
constructor(expression: string, timezone?: string);
|
|
17
|
+
/**
|
|
18
|
+
* Parse cron expression into schedule object
|
|
19
|
+
* Format: minute hour dayOfMonth month dayOfWeek
|
|
20
|
+
* Each field can be: *, number, range (1-5), step (*\/2), list (1,3,5)
|
|
21
|
+
*/
|
|
22
|
+
private parse;
|
|
23
|
+
/**
|
|
24
|
+
* Parse individual cron field
|
|
25
|
+
*/
|
|
26
|
+
private parseField;
|
|
27
|
+
/**
|
|
28
|
+
* Generate range of numbers [min, max]
|
|
29
|
+
*/
|
|
30
|
+
private range;
|
|
31
|
+
/**
|
|
32
|
+
* Calculate next run time from given date
|
|
33
|
+
*/
|
|
34
|
+
getNextRun(from?: Date): NextRunResult;
|
|
35
|
+
/**
|
|
36
|
+
* Calculate all next N run times
|
|
37
|
+
*/
|
|
38
|
+
getNextRuns(count: number, from?: Date): Date[];
|
|
39
|
+
/**
|
|
40
|
+
* Core algorithm to find next matching time
|
|
41
|
+
*/
|
|
42
|
+
private calculateNextRun;
|
|
43
|
+
/**
|
|
44
|
+
* Check if date matches cron schedule
|
|
45
|
+
*/
|
|
46
|
+
private matches;
|
|
47
|
+
/**
|
|
48
|
+
* Validate if expression is valid
|
|
49
|
+
*/
|
|
50
|
+
static validate(expression: string): {
|
|
51
|
+
valid: boolean;
|
|
52
|
+
error?: string;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Get human-readable description
|
|
56
|
+
*/
|
|
57
|
+
describe(): string;
|
|
58
|
+
/**
|
|
59
|
+
* Get schedule details
|
|
60
|
+
*/
|
|
61
|
+
getSchedule(): CronSchedule;
|
|
62
|
+
}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
// Production-grade Cron Expression Parser
|
|
2
|
+
// Supports standard 5-field cron syntax + extended macros
|
|
3
|
+
// Macro definitions for common schedules
|
|
4
|
+
const CRON_MACROS = {
|
|
5
|
+
'@yearly': '0 0 1 1 *',
|
|
6
|
+
'@annually': '0 0 1 1 *',
|
|
7
|
+
'@monthly': '0 0 1 * *',
|
|
8
|
+
'@weekly': '0 0 * * 0',
|
|
9
|
+
'@daily': '0 0 * * *',
|
|
10
|
+
'@midnight': '0 0 * * *',
|
|
11
|
+
'@hourly': '0 * * * *',
|
|
12
|
+
'@every-15m': '*/15 * * * *',
|
|
13
|
+
'@every-30m': '*/30 * * * *',
|
|
14
|
+
};
|
|
15
|
+
export class CronParser {
|
|
16
|
+
schedule;
|
|
17
|
+
timezone;
|
|
18
|
+
originalExpression;
|
|
19
|
+
constructor(expression, timezone = 'UTC') {
|
|
20
|
+
this.originalExpression = expression;
|
|
21
|
+
this.timezone = timezone;
|
|
22
|
+
// Handle macros
|
|
23
|
+
const normalizedExpression = CRON_MACROS[expression.toLowerCase()] || expression;
|
|
24
|
+
this.schedule = this.parse(normalizedExpression);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Parse cron expression into schedule object
|
|
28
|
+
* Format: minute hour dayOfMonth month dayOfWeek
|
|
29
|
+
* Each field can be: *, number, range (1-5), step (*\/2), list (1,3,5)
|
|
30
|
+
*/
|
|
31
|
+
parse(expression) {
|
|
32
|
+
const fields = expression.trim().split(/\s+/);
|
|
33
|
+
if (fields.length !== 5) {
|
|
34
|
+
throw new Error(`Invalid cron expression "${this.originalExpression}". Expected 5 fields (minute hour day month weekday), got ${fields.length}`);
|
|
35
|
+
}
|
|
36
|
+
const [minuteField, hourField, dayField, monthField, weekdayField] = fields;
|
|
37
|
+
return {
|
|
38
|
+
minutes: this.parseField(minuteField, 0, 59, 'minute'),
|
|
39
|
+
hours: this.parseField(hourField, 0, 23, 'hour'),
|
|
40
|
+
daysOfMonth: this.parseField(dayField, 1, 31, 'day of month'),
|
|
41
|
+
months: this.parseField(monthField, 1, 12, 'month'),
|
|
42
|
+
daysOfWeek: this.parseField(weekdayField, 0, 6, 'day of week'),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Parse individual cron field
|
|
47
|
+
*/
|
|
48
|
+
parseField(field, min, max, fieldName) {
|
|
49
|
+
if (!field || field.trim() === '') {
|
|
50
|
+
throw new Error(`Empty field for ${fieldName}`);
|
|
51
|
+
}
|
|
52
|
+
// Wildcard - all values
|
|
53
|
+
if (field === '*') {
|
|
54
|
+
return this.range(min, max);
|
|
55
|
+
}
|
|
56
|
+
const values = new Set();
|
|
57
|
+
// Handle comma-separated values
|
|
58
|
+
const parts = field.split(',');
|
|
59
|
+
for (const part of parts) {
|
|
60
|
+
// Step values: */5 or 1-10/2
|
|
61
|
+
if (part.includes('/')) {
|
|
62
|
+
const [rangeOrWildcard, stepStr] = part.split('/');
|
|
63
|
+
const step = parseInt(stepStr, 10);
|
|
64
|
+
if (isNaN(step) || step <= 0) {
|
|
65
|
+
throw new Error(`Invalid step value "${stepStr}" in ${fieldName}`);
|
|
66
|
+
}
|
|
67
|
+
let rangeStart = min;
|
|
68
|
+
let rangeEnd = max;
|
|
69
|
+
if (rangeOrWildcard !== '*') {
|
|
70
|
+
if (rangeOrWildcard.includes('-')) {
|
|
71
|
+
const [start, end] = rangeOrWildcard.split('-').map(v => parseInt(v, 10));
|
|
72
|
+
rangeStart = start;
|
|
73
|
+
rangeEnd = end;
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
rangeStart = parseInt(rangeOrWildcard, 10);
|
|
77
|
+
rangeEnd = max;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
for (let i = rangeStart; i <= rangeEnd; i += step) {
|
|
81
|
+
if (i >= min && i <= max) {
|
|
82
|
+
values.add(i);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// Range: 1-5
|
|
87
|
+
else if (part.includes('-')) {
|
|
88
|
+
const [startStr, endStr] = part.split('-');
|
|
89
|
+
const start = parseInt(startStr, 10);
|
|
90
|
+
const end = parseInt(endStr, 10);
|
|
91
|
+
if (isNaN(start) || isNaN(end)) {
|
|
92
|
+
throw new Error(`Invalid range "${part}" in ${fieldName}`);
|
|
93
|
+
}
|
|
94
|
+
if (start > end) {
|
|
95
|
+
throw new Error(`Invalid range "${part}" in ${fieldName}: start > end`);
|
|
96
|
+
}
|
|
97
|
+
for (let i = start; i <= end; i++) {
|
|
98
|
+
if (i >= min && i <= max) {
|
|
99
|
+
values.add(i);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// Single value
|
|
104
|
+
else {
|
|
105
|
+
const value = parseInt(part, 10);
|
|
106
|
+
if (isNaN(value)) {
|
|
107
|
+
throw new Error(`Invalid value "${part}" in ${fieldName}`);
|
|
108
|
+
}
|
|
109
|
+
if (value < min || value > max) {
|
|
110
|
+
throw new Error(`Value ${value} out of range [${min}-${max}] in ${fieldName}`);
|
|
111
|
+
}
|
|
112
|
+
values.add(value);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (values.size === 0) {
|
|
116
|
+
throw new Error(`No valid values parsed for ${fieldName}`);
|
|
117
|
+
}
|
|
118
|
+
return Array.from(values).sort((a, b) => a - b);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Generate range of numbers [min, max]
|
|
122
|
+
*/
|
|
123
|
+
range(min, max) {
|
|
124
|
+
const result = [];
|
|
125
|
+
for (let i = min; i <= max; i++) {
|
|
126
|
+
result.push(i);
|
|
127
|
+
}
|
|
128
|
+
return result;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Calculate next run time from given date
|
|
132
|
+
*/
|
|
133
|
+
getNextRun(from = new Date()) {
|
|
134
|
+
const next = this.calculateNextRun(from);
|
|
135
|
+
const delay = next.getTime() - from.getTime();
|
|
136
|
+
return { next, delay };
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Calculate all next N run times
|
|
140
|
+
*/
|
|
141
|
+
getNextRuns(count, from = new Date()) {
|
|
142
|
+
const runs = [];
|
|
143
|
+
let current = from;
|
|
144
|
+
for (let i = 0; i < count; i++) {
|
|
145
|
+
const { next } = this.getNextRun(current);
|
|
146
|
+
runs.push(next);
|
|
147
|
+
current = new Date(next.getTime() + 1000); // Move 1 second forward
|
|
148
|
+
}
|
|
149
|
+
return runs;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Core algorithm to find next matching time
|
|
153
|
+
*/
|
|
154
|
+
calculateNextRun(from) {
|
|
155
|
+
// Start from next minute (reset seconds and milliseconds)
|
|
156
|
+
let candidate = new Date(from);
|
|
157
|
+
candidate.setSeconds(0, 0);
|
|
158
|
+
candidate.setMinutes(candidate.getMinutes() + 1);
|
|
159
|
+
// Prevent infinite loop with max iterations
|
|
160
|
+
let iterations = 0;
|
|
161
|
+
const maxIterations = 4 * 365 * 24 * 60; // 4 years in minutes
|
|
162
|
+
while (iterations < maxIterations) {
|
|
163
|
+
if (this.matches(candidate)) {
|
|
164
|
+
return candidate;
|
|
165
|
+
}
|
|
166
|
+
// Move to next minute
|
|
167
|
+
candidate = new Date(candidate.getTime() + 60000);
|
|
168
|
+
iterations++;
|
|
169
|
+
}
|
|
170
|
+
throw new Error(`Could not find next run time for cron expression "${this.originalExpression}" within 4 years`);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Check if date matches cron schedule
|
|
174
|
+
*/
|
|
175
|
+
matches(date) {
|
|
176
|
+
const minute = date.getMinutes();
|
|
177
|
+
const hour = date.getHours();
|
|
178
|
+
const dayOfMonth = date.getDate();
|
|
179
|
+
const month = date.getMonth() + 1; // JS months are 0-indexed
|
|
180
|
+
const dayOfWeek = date.getDay();
|
|
181
|
+
// All fields must match
|
|
182
|
+
return (this.schedule.minutes.includes(minute) &&
|
|
183
|
+
this.schedule.hours.includes(hour) &&
|
|
184
|
+
this.schedule.daysOfMonth.includes(dayOfMonth) &&
|
|
185
|
+
this.schedule.months.includes(month) &&
|
|
186
|
+
this.schedule.daysOfWeek.includes(dayOfWeek));
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Validate if expression is valid
|
|
190
|
+
*/
|
|
191
|
+
static validate(expression) {
|
|
192
|
+
try {
|
|
193
|
+
new CronParser(expression);
|
|
194
|
+
return { valid: true };
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
return {
|
|
198
|
+
valid: false,
|
|
199
|
+
error: error instanceof Error ? error.message : String(error),
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Get human-readable description
|
|
205
|
+
*/
|
|
206
|
+
describe() {
|
|
207
|
+
if (CRON_MACROS[this.originalExpression.toLowerCase()]) {
|
|
208
|
+
return this.originalExpression;
|
|
209
|
+
}
|
|
210
|
+
const parts = [];
|
|
211
|
+
// Minutes
|
|
212
|
+
if (this.schedule.minutes.length === 60) {
|
|
213
|
+
parts.push('every minute');
|
|
214
|
+
}
|
|
215
|
+
else if (this.schedule.minutes.length === 1) {
|
|
216
|
+
parts.push(`at minute ${this.schedule.minutes[0]}`);
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
parts.push(`at minutes ${this.schedule.minutes.join(', ')}`);
|
|
220
|
+
}
|
|
221
|
+
// Hours
|
|
222
|
+
if (this.schedule.hours.length !== 24) {
|
|
223
|
+
if (this.schedule.hours.length === 1) {
|
|
224
|
+
parts.push(`at hour ${this.schedule.hours[0]}`);
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
parts.push(`at hours ${this.schedule.hours.join(', ')}`);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return parts.join(', ');
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Get schedule details
|
|
234
|
+
*/
|
|
235
|
+
getSchedule() {
|
|
236
|
+
return { ...this.schedule };
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=cron-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cron-parser.js","sourceRoot":"","sources":["../../../src/core/jobs/cron-parser.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,0DAA0D;AAe1D,yCAAyC;AACzC,MAAM,WAAW,GAA2B;IAC1C,SAAS,EAAE,WAAW;IACtB,WAAW,EAAE,WAAW;IACxB,UAAU,EAAE,WAAW;IACvB,SAAS,EAAE,WAAW;IACtB,QAAQ,EAAE,WAAW;IACrB,WAAW,EAAE,WAAW;IACxB,SAAS,EAAE,WAAW;IACtB,YAAY,EAAE,cAAc;IAC5B,YAAY,EAAE,cAAc;CAC7B,CAAC;AAEF,MAAM,OAAO,UAAU;IACb,QAAQ,CAAe;IACvB,QAAQ,CAAS;IACjB,kBAAkB,CAAS;IAEnC,YAAY,UAAkB,EAAE,WAAmB,KAAK;QACtD,IAAI,CAAC,kBAAkB,GAAG,UAAU,CAAC;QACrC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAEzB,gBAAgB;QAChB,MAAM,oBAAoB,GAAG,WAAW,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,IAAI,UAAU,CAAC;QACjF,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACnD,CAAC;IAED;;;;OAIG;IACK,KAAK,CAAC,UAAkB;QAC9B,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAE9C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CACb,4BAA4B,IAAI,CAAC,kBAAkB,6DAA6D,MAAM,CAAC,MAAM,EAAE,CAChI,CAAC;QACJ,CAAC;QAED,MAAM,CAAC,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,YAAY,CAAC,GAAG,MAAM,CAAC;QAE5E,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,EAAE,EAAE,EAAE,QAAQ,CAAC;YACtD,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC;YAChD,WAAW,EAAE,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,cAAc,CAAC;YAC7D,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC;YACnD,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC,EAAE,CAAC,EAAE,aAAa,CAAC;SAC/D,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,UAAU,CAAC,KAAa,EAAE,GAAW,EAAE,GAAW,EAAE,SAAiB;QAC3E,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,mBAAmB,SAAS,EAAE,CAAC,CAAC;QAClD,CAAC;QAED,wBAAwB;QACxB,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;YAClB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC9B,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;QAEjC,gCAAgC;QAChC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAE/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,6BAA6B;YAC7B,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvB,MAAM,CAAC,eAAe,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACnD,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gBAEnC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;oBAC7B,MAAM,IAAI,KAAK,CAAC,uBAAuB,OAAO,QAAQ,SAAS,EAAE,CAAC,CAAC;gBACrE,CAAC;gBAED,IAAI,UAAU,GAAG,GAAG,CAAC;gBACrB,IAAI,QAAQ,GAAG,GAAG,CAAC;gBAEnB,IAAI,eAAe,KAAK,GAAG,EAAE,CAAC;oBAC5B,IAAI,eAAe,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;wBAClC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;wBAC1E,UAAU,GAAG,KAAK,CAAC;wBACnB,QAAQ,GAAG,GAAG,CAAC;oBACjB,CAAC;yBAAM,CAAC;wBACN,UAAU,GAAG,QAAQ,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;wBAC3C,QAAQ,GAAG,GAAG,CAAC;oBACjB,CAAC;gBACH,CAAC;gBAED,KAAK,IAAI,CAAC,GAAG,UAAU,EAAE,CAAC,IAAI,QAAQ,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;oBAClD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;wBACzB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;oBAChB,CAAC;gBACH,CAAC;YACH,CAAC;YACD,aAAa;iBACR,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC5B,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAC3C,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;gBACrC,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBAEjC,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC/B,MAAM,IAAI,KAAK,CAAC,kBAAkB,IAAI,QAAQ,SAAS,EAAE,CAAC,CAAC;gBAC7D,CAAC;gBAED,IAAI,KAAK,GAAG,GAAG,EAAE,CAAC;oBAChB,MAAM,IAAI,KAAK,CAAC,kBAAkB,IAAI,QAAQ,SAAS,eAAe,CAAC,CAAC;gBAC1E,CAAC;gBAED,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;oBAClC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;wBACzB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;oBAChB,CAAC;gBACH,CAAC;YACH,CAAC;YACD,eAAe;iBACV,CAAC;gBACJ,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBAEjC,IAAI,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;oBACjB,MAAM,IAAI,KAAK,CAAC,kBAAkB,IAAI,QAAQ,SAAS,EAAE,CAAC,CAAC;gBAC7D,CAAC;gBAED,IAAI,KAAK,GAAG,GAAG,IAAI,KAAK,GAAG,GAAG,EAAE,CAAC;oBAC/B,MAAM,IAAI,KAAK,CAAC,SAAS,KAAK,kBAAkB,GAAG,IAAI,GAAG,QAAQ,SAAS,EAAE,CAAC,CAAC;gBACjF,CAAC;gBAED,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACpB,CAAC;QACH,CAAC;QAED,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,8BAA8B,SAAS,EAAE,CAAC,CAAC;QAC7D,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAClD,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,GAAW,EAAE,GAAW;QACpC,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,KAAK,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;YAChC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACI,UAAU,CAAC,OAAa,IAAI,IAAI,EAAE;QACvC,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAE9C,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACzB,CAAC;IAED;;OAEG;IACI,WAAW,CAAC,KAAa,EAAE,OAAa,IAAI,IAAI,EAAE;QACvD,MAAM,IAAI,GAAW,EAAE,CAAC;QACxB,IAAI,OAAO,GAAG,IAAI,CAAC;QAEnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/B,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YAC1C,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChB,OAAO,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,wBAAwB;QACrE,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACK,gBAAgB,CAAC,IAAU;QACjC,0DAA0D;QAC1D,IAAI,SAAS,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,SAAS,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC3B,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC;QAEjD,4CAA4C;QAC5C,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,MAAM,aAAa,GAAG,CAAC,GAAG,GAAG,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,qBAAqB;QAE9D,OAAO,UAAU,GAAG,aAAa,EAAE,CAAC;YAClC,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC5B,OAAO,SAAS,CAAC;YACnB,CAAC;YAED,sBAAsB;YACtB,SAAS,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,CAAC;YAClD,UAAU,EAAE,CAAC;QACf,CAAC;QAED,MAAM,IAAI,KAAK,CACb,qDAAqD,IAAI,CAAC,kBAAkB,kBAAkB,CAC/F,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,OAAO,CAAC,IAAU;QACxB,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC7B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,0BAA0B;QAC7D,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAEhC,wBAAwB;QACxB,OAAO,CACL,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;YACtC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;YAClC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC;YAC9C,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;YACpC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,CAC7C,CAAC;IACJ,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,QAAQ,CAAC,UAAkB;QACvC,IAAI,CAAC;YACH,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC;YAC3B,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACzB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO;gBACL,KAAK,EAAE,KAAK;gBACZ,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAC9D,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACI,QAAQ;QACb,IAAI,WAAW,CAAC,IAAI,CAAC,kBAAkB,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;YACvD,OAAO,IAAI,CAAC,kBAAkB,CAAC;QACjC,CAAC;QAED,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,UAAU;QACV,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;YACxC,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC7B,CAAC;aAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9C,KAAK,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACtD,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/D,CAAC;QAED,QAAQ;QACR,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;YACtC,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACrC,KAAK,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAClD,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED;;OAEG;IACI,WAAW;QAChB,OAAO,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;IAC9B,CAAC;CACF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { CronParser } from './cron-parser.js';
|
|
2
|
+
export { JobStateManager } from './job-state-manager.js';
|
|
3
|
+
export { LeaderElection } from './leader-election.js';
|
|
4
|
+
export { JobExecutor } from './job-executor.js';
|
|
5
|
+
export { JobScheduler } from './job-scheduler.js';
|
|
6
|
+
export { JobHealthChecker, parseInterval, formatDuration, everyInterval, cronSchedule, oneTimeAt, createJob, JobBuilder, } from './utils.js';
|
|
7
|
+
export type * from './types.js';
|
|
8
|
+
export type { CronSchedule, NextRunResult } from './cron-parser.js';
|
|
9
|
+
export type { JobExecution, JobState, JobHistory, StateManagerOptions, } from './job-state-manager.js';
|
|
10
|
+
export type { LeaderElectionOptions, LeaderInfo } from './leader-election.js';
|
|
11
|
+
export type { JobExecutorOptions, JobFunction, ExecutionContext, ExecutionResult, } from './job-executor.js';
|
|
12
|
+
export type { JobScheduleType, JobSchedule, JobOptions, Job, JobSchedulerOptions, } from './job-scheduler.js';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// Job System - Production-grade background job scheduling for MoroJS
|
|
2
|
+
// Main entry point and public API
|
|
3
|
+
export { CronParser } from './cron-parser.js';
|
|
4
|
+
export { JobStateManager } from './job-state-manager.js';
|
|
5
|
+
export { LeaderElection } from './leader-election.js';
|
|
6
|
+
export { JobExecutor } from './job-executor.js';
|
|
7
|
+
export { JobScheduler } from './job-scheduler.js';
|
|
8
|
+
export { JobHealthChecker, parseInterval, formatDuration, everyInterval, cronSchedule, oneTimeAt, createJob, JobBuilder, } from './utils.js';
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/jobs/index.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,kCAAkC;AAElC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,aAAa,EACb,YAAY,EACZ,SAAS,EACT,SAAS,EACT,UAAU,GACX,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import { Logger } from '../../types/logger.js';
|
|
3
|
+
type AbortSignal = {
|
|
4
|
+
readonly aborted: boolean;
|
|
5
|
+
addEventListener(type: 'abort', listener: () => void, options?: {
|
|
6
|
+
once: boolean;
|
|
7
|
+
}): void;
|
|
8
|
+
removeEventListener(type: 'abort', listener: () => void): void;
|
|
9
|
+
};
|
|
10
|
+
type AbortController = {
|
|
11
|
+
readonly signal: AbortSignal;
|
|
12
|
+
abort(): void;
|
|
13
|
+
};
|
|
14
|
+
declare global {
|
|
15
|
+
interface GlobalThis {
|
|
16
|
+
AbortController: new () => AbortController;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export interface JobExecutorOptions {
|
|
20
|
+
maxRetries?: number;
|
|
21
|
+
retryDelay?: number;
|
|
22
|
+
retryBackoff?: 'linear' | 'exponential';
|
|
23
|
+
retryBackoffMultiplier?: number;
|
|
24
|
+
maxRetryDelay?: number;
|
|
25
|
+
timeout?: number;
|
|
26
|
+
enableCircuitBreaker?: boolean;
|
|
27
|
+
circuitBreakerThreshold?: number;
|
|
28
|
+
circuitBreakerResetTimeout?: number;
|
|
29
|
+
enableMemoryMonitoring?: boolean;
|
|
30
|
+
memoryThreshold?: number;
|
|
31
|
+
}
|
|
32
|
+
export interface JobFunction {
|
|
33
|
+
(...args: any[]): Promise<any> | any;
|
|
34
|
+
}
|
|
35
|
+
export interface ExecutionContext {
|
|
36
|
+
jobId: string;
|
|
37
|
+
executionId: string;
|
|
38
|
+
attempt: number;
|
|
39
|
+
startTime: Date;
|
|
40
|
+
metadata?: Record<string, any>;
|
|
41
|
+
}
|
|
42
|
+
export interface ExecutionResult {
|
|
43
|
+
success: boolean;
|
|
44
|
+
value?: any;
|
|
45
|
+
error?: Error;
|
|
46
|
+
attempts: number;
|
|
47
|
+
duration: number;
|
|
48
|
+
memoryUsed?: number;
|
|
49
|
+
circuitBreakerTripped?: boolean;
|
|
50
|
+
timedOut?: boolean;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* JobExecutor - Executes jobs with production-grade resilience
|
|
54
|
+
* Features:
|
|
55
|
+
* - Configurable retry with exponential backoff + jitter
|
|
56
|
+
* - Timeout enforcement
|
|
57
|
+
* - Circuit breaker integration
|
|
58
|
+
* - Memory leak detection
|
|
59
|
+
* - Graceful cancellation
|
|
60
|
+
*/
|
|
61
|
+
export declare class JobExecutor extends EventEmitter {
|
|
62
|
+
private options;
|
|
63
|
+
private logger;
|
|
64
|
+
private circuitBreakers;
|
|
65
|
+
private activeExecutions;
|
|
66
|
+
private isShuttingDown;
|
|
67
|
+
constructor(logger: Logger, options?: JobExecutorOptions);
|
|
68
|
+
/**
|
|
69
|
+
* Execute a job with full resilience features
|
|
70
|
+
*/
|
|
71
|
+
execute(jobId: string, executionId: string, jobFn: JobFunction, context?: ExecutionContext): Promise<ExecutionResult>;
|
|
72
|
+
/**
|
|
73
|
+
* Execute job function with timeout
|
|
74
|
+
*/
|
|
75
|
+
private executeWithTimeout;
|
|
76
|
+
/**
|
|
77
|
+
* Calculate retry delay with backoff and jitter
|
|
78
|
+
*/
|
|
79
|
+
private calculateRetryDelay;
|
|
80
|
+
/**
|
|
81
|
+
* Sleep helper
|
|
82
|
+
*/
|
|
83
|
+
private sleep;
|
|
84
|
+
/**
|
|
85
|
+
* Get or create circuit breaker for job
|
|
86
|
+
*/
|
|
87
|
+
private getCircuitBreaker;
|
|
88
|
+
/**
|
|
89
|
+
* Check memory usage before execution
|
|
90
|
+
*/
|
|
91
|
+
private checkMemoryUsage;
|
|
92
|
+
/**
|
|
93
|
+
* Get current memory usage in MB
|
|
94
|
+
*/
|
|
95
|
+
private getMemoryUsage;
|
|
96
|
+
/**
|
|
97
|
+
* Cancel a running execution
|
|
98
|
+
*/
|
|
99
|
+
cancelExecution(executionId: string): boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Cancel all running executions
|
|
102
|
+
*/
|
|
103
|
+
cancelAllExecutions(): void;
|
|
104
|
+
/**
|
|
105
|
+
* Get active execution count
|
|
106
|
+
*/
|
|
107
|
+
getActiveExecutionCount(): number;
|
|
108
|
+
/**
|
|
109
|
+
* Get circuit breaker status for job
|
|
110
|
+
*/
|
|
111
|
+
getCircuitBreakerStatus(jobId: string): {
|
|
112
|
+
exists: boolean;
|
|
113
|
+
state?: string;
|
|
114
|
+
failures?: number;
|
|
115
|
+
threshold?: number;
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* Reset circuit breaker for job
|
|
119
|
+
*/
|
|
120
|
+
resetCircuitBreaker(jobId: string): boolean;
|
|
121
|
+
/**
|
|
122
|
+
* Update executor options at runtime
|
|
123
|
+
*/
|
|
124
|
+
updateOptions(options: Partial<JobExecutorOptions>): void;
|
|
125
|
+
/**
|
|
126
|
+
* Get current options
|
|
127
|
+
*/
|
|
128
|
+
getOptions(): Required<JobExecutorOptions>;
|
|
129
|
+
/**
|
|
130
|
+
* Shutdown and cleanup
|
|
131
|
+
*/
|
|
132
|
+
shutdown(gracePeriod?: number): Promise<void>;
|
|
133
|
+
}
|
|
134
|
+
export {};
|