glasswork 0.12.1 → 0.12.2
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/dist/core/types.d.ts +6 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/email/compiler/code-generator.d.ts +11 -0
- package/dist/email/compiler/code-generator.d.ts.map +1 -0
- package/dist/email/compiler/code-generator.js +319 -0
- package/dist/email/compiler/code-generator.js.map +1 -0
- package/dist/http/route-helpers.d.ts +4 -9
- package/dist/http/route-helpers.d.ts.map +1 -1
- package/dist/http/route-helpers.js +1 -0
- package/dist/http/route-helpers.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/jobs/define-job.d.ts +25 -0
- package/dist/jobs/define-job.d.ts.map +1 -0
- package/dist/jobs/define-job.js +12 -0
- package/dist/jobs/define-job.js.map +1 -0
- package/dist/jobs/drivers/mock-driver.d.ts +38 -0
- package/dist/jobs/drivers/mock-driver.d.ts.map +1 -0
- package/dist/jobs/drivers/mock-driver.js +76 -0
- package/dist/jobs/drivers/mock-driver.js.map +1 -0
- package/dist/jobs/drivers/sqs-driver.d.ts +52 -0
- package/dist/jobs/drivers/sqs-driver.d.ts.map +1 -0
- package/dist/jobs/drivers/sqs-driver.js +191 -0
- package/dist/jobs/drivers/sqs-driver.js.map +1 -0
- package/dist/jobs/errors.d.ts +40 -0
- package/dist/jobs/errors.d.ts.map +1 -0
- package/dist/jobs/errors.js +61 -0
- package/dist/jobs/errors.js.map +1 -0
- package/dist/jobs/index.d.ts +11 -0
- package/dist/jobs/index.d.ts.map +1 -0
- package/dist/jobs/index.js +10 -0
- package/dist/jobs/index.js.map +1 -0
- package/dist/jobs/job-registry.d.ts +33 -0
- package/dist/jobs/job-registry.d.ts.map +1 -0
- package/dist/jobs/job-registry.js +56 -0
- package/dist/jobs/job-registry.js.map +1 -0
- package/dist/jobs/job-service.d.ts +44 -0
- package/dist/jobs/job-service.d.ts.map +1 -0
- package/dist/jobs/job-service.js +105 -0
- package/dist/jobs/job-service.js.map +1 -0
- package/dist/jobs/periodic-job.d.ts +6 -0
- package/dist/jobs/periodic-job.d.ts.map +1 -0
- package/dist/jobs/periodic-job.js +11 -0
- package/dist/jobs/periodic-job.js.map +1 -0
- package/dist/jobs/schedule-constants.d.ts +9 -0
- package/dist/jobs/schedule-constants.d.ts.map +1 -0
- package/dist/jobs/schedule-constants.js +9 -0
- package/dist/jobs/schedule-constants.js.map +1 -0
- package/dist/jobs/scheduler.d.ts +17 -0
- package/dist/jobs/scheduler.d.ts.map +1 -0
- package/dist/jobs/scheduler.js +47 -0
- package/dist/jobs/scheduler.js.map +1 -0
- package/dist/jobs/types.d.ts +156 -0
- package/dist/jobs/types.d.ts.map +1 -0
- package/dist/jobs/types.js +2 -0
- package/dist/jobs/types.js.map +1 -0
- package/dist/jobs/utils.d.ts +24 -0
- package/dist/jobs/utils.d.ts.map +1 -0
- package/dist/jobs/utils.js +69 -0
- package/dist/jobs/utils.js.map +1 -0
- package/dist/jobs/worker.d.ts +36 -0
- package/dist/jobs/worker.d.ts.map +1 -0
- package/dist/jobs/worker.js +260 -0
- package/dist/jobs/worker.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Duration, EnqueueResult, JobMessage, QueueDriver, ReceivedJob, ReceiveOptions } from '../types.js';
|
|
2
|
+
export interface MockEnqueuedJob {
|
|
3
|
+
message: JobMessage & {
|
|
4
|
+
jobId: string;
|
|
5
|
+
};
|
|
6
|
+
at?: Date;
|
|
7
|
+
delay?: Duration;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* In-memory queue driver for testing.
|
|
11
|
+
*/
|
|
12
|
+
export declare class MockQueueDriver implements QueueDriver {
|
|
13
|
+
readonly name = "mock";
|
|
14
|
+
private counter;
|
|
15
|
+
private failNext?;
|
|
16
|
+
readonly enqueued: MockEnqueuedJob[];
|
|
17
|
+
readonly acks: ReceivedJob[];
|
|
18
|
+
readonly nacks: Array<{
|
|
19
|
+
job: ReceivedJob;
|
|
20
|
+
error?: Error;
|
|
21
|
+
}>;
|
|
22
|
+
/**
|
|
23
|
+
* Simulate the next enqueue call failing.
|
|
24
|
+
*/
|
|
25
|
+
simulateFailure(error?: Error): void;
|
|
26
|
+
/**
|
|
27
|
+
* Clear stored jobs and reset counters.
|
|
28
|
+
*/
|
|
29
|
+
clear(): void;
|
|
30
|
+
get lastJob(): MockEnqueuedJob | undefined;
|
|
31
|
+
enqueue(message: JobMessage): Promise<EnqueueResult>;
|
|
32
|
+
enqueueAt(message: JobMessage, at: Date): Promise<EnqueueResult>;
|
|
33
|
+
enqueueIn(message: JobMessage, delay: Duration): Promise<EnqueueResult>;
|
|
34
|
+
receive(_options?: ReceiveOptions): Promise<ReceivedJob[]>;
|
|
35
|
+
ack(job: ReceivedJob): Promise<void>;
|
|
36
|
+
nack(job: ReceivedJob, error?: Error): Promise<void>;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=mock-driver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock-driver.d.ts","sourceRoot":"","sources":["../../../src/jobs/drivers/mock-driver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EACR,aAAa,EACb,UAAU,EACV,WAAW,EACX,WAAW,EACX,cAAc,EACf,MAAM,aAAa,CAAC;AAGrB,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,UAAU,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,EAAE,CAAC,EAAE,IAAI,CAAC;IACV,KAAK,CAAC,EAAE,QAAQ,CAAC;CAClB;AAED;;GAEG;AACH,qBAAa,eAAgB,YAAW,WAAW;IACjD,QAAQ,CAAC,IAAI,UAAU;IACvB,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,QAAQ,CAAC,CAAQ;IACzB,QAAQ,CAAC,QAAQ,EAAE,eAAe,EAAE,CAAM;IAC1C,QAAQ,CAAC,IAAI,EAAE,WAAW,EAAE,CAAM;IAClC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,WAAW,CAAC;QAAC,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE,CAAC,CAAM;IAEhE;;OAEG;IACH,eAAe,CAAC,KAAK,QAAoC,GAAG,IAAI;IAIhE;;OAEG;IACH,KAAK,IAAI,IAAI;IAQb,IAAI,OAAO,IAAI,eAAe,GAAG,SAAS,CAEzC;IAEK,OAAO,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC;IAoBpD,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC;IAShE,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,aAAa,CAAC;IASvE,OAAO,CAAC,QAAQ,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAO1D,GAAG,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpC,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;CAG3D"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { generateJobId } from '../utils.js';
|
|
2
|
+
/**
|
|
3
|
+
* In-memory queue driver for testing.
|
|
4
|
+
*/
|
|
5
|
+
export class MockQueueDriver {
|
|
6
|
+
name = 'mock';
|
|
7
|
+
counter = 0;
|
|
8
|
+
failNext;
|
|
9
|
+
enqueued = [];
|
|
10
|
+
acks = [];
|
|
11
|
+
nacks = [];
|
|
12
|
+
/**
|
|
13
|
+
* Simulate the next enqueue call failing.
|
|
14
|
+
*/
|
|
15
|
+
simulateFailure(error = new Error('Mock enqueue failure')) {
|
|
16
|
+
this.failNext = error;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Clear stored jobs and reset counters.
|
|
20
|
+
*/
|
|
21
|
+
clear() {
|
|
22
|
+
this.enqueued.length = 0;
|
|
23
|
+
this.acks.length = 0;
|
|
24
|
+
this.nacks.length = 0;
|
|
25
|
+
this.counter = 0;
|
|
26
|
+
this.failNext = undefined;
|
|
27
|
+
}
|
|
28
|
+
get lastJob() {
|
|
29
|
+
return this.enqueued.at(-1);
|
|
30
|
+
}
|
|
31
|
+
async enqueue(message) {
|
|
32
|
+
if (this.failNext) {
|
|
33
|
+
const error = this.failNext;
|
|
34
|
+
this.failNext = undefined;
|
|
35
|
+
throw error;
|
|
36
|
+
}
|
|
37
|
+
const jobId = message.jobId ?? generateJobId();
|
|
38
|
+
const result = {
|
|
39
|
+
messageId: `mock-${++this.counter}`,
|
|
40
|
+
jobId,
|
|
41
|
+
};
|
|
42
|
+
this.enqueued.push({
|
|
43
|
+
message: { ...message, jobId },
|
|
44
|
+
});
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
async enqueueAt(message, at) {
|
|
48
|
+
const result = await this.enqueue(message);
|
|
49
|
+
const last = this.enqueued[this.enqueued.length - 1];
|
|
50
|
+
if (last) {
|
|
51
|
+
last.at = at;
|
|
52
|
+
}
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
async enqueueIn(message, delay) {
|
|
56
|
+
const result = await this.enqueue(message);
|
|
57
|
+
const last = this.enqueued[this.enqueued.length - 1];
|
|
58
|
+
if (last) {
|
|
59
|
+
last.delay = delay;
|
|
60
|
+
}
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
async receive(_options) {
|
|
64
|
+
return this.enqueued.map(({ message }) => ({
|
|
65
|
+
message,
|
|
66
|
+
receiptHandle: message.jobId,
|
|
67
|
+
}));
|
|
68
|
+
}
|
|
69
|
+
async ack(job) {
|
|
70
|
+
this.acks.push(job);
|
|
71
|
+
}
|
|
72
|
+
async nack(job, error) {
|
|
73
|
+
this.nacks.push({ job, error });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=mock-driver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock-driver.js","sourceRoot":"","sources":["../../../src/jobs/drivers/mock-driver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { SQSClient as SQSClientType } from '@aws-sdk/client-sqs';
|
|
2
|
+
import type { Duration, EnqueueResult, JobMessage, QueueDriver, ReceivedJob, ReceiveOptions } from '../types.js';
|
|
3
|
+
export interface SQSDriverConfig {
|
|
4
|
+
/** AWS region */
|
|
5
|
+
region: string;
|
|
6
|
+
/** Queue URL mapping (queue name -> URL) */
|
|
7
|
+
queues: Record<string, string>;
|
|
8
|
+
/** Default queue name */
|
|
9
|
+
defaultQueue?: string;
|
|
10
|
+
/** Custom endpoint (for LocalStack) */
|
|
11
|
+
endpoint?: string;
|
|
12
|
+
/**
|
|
13
|
+
* DynamoDB table for scheduled jobs (used when longDelayStrategy is "dynamodb").
|
|
14
|
+
* Not required when using the default self-rescheduling strategy.
|
|
15
|
+
*/
|
|
16
|
+
schedulerTable?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Strategy for delays over 15 minutes (SQS maximum).
|
|
19
|
+
* - "self-reschedule" (default): the job re-enqueues itself in 15-minute slices until due.
|
|
20
|
+
* - "dynamodb": store in DynamoDB and poll via the scheduler Lambda.
|
|
21
|
+
*/
|
|
22
|
+
longDelayStrategy?: 'self-reschedule' | 'dynamodb';
|
|
23
|
+
/** Optional pre-configured SQS client */
|
|
24
|
+
client?: SQSClientType;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* AWS SQS queue driver (Phase 1: enqueue only).
|
|
28
|
+
*/
|
|
29
|
+
export declare class SQSQueueDriver implements QueueDriver {
|
|
30
|
+
private readonly config;
|
|
31
|
+
readonly name = "sqs";
|
|
32
|
+
private client;
|
|
33
|
+
private schedulerClientPromise;
|
|
34
|
+
constructor(config: SQSDriverConfig);
|
|
35
|
+
/**
|
|
36
|
+
* Lazily initialize the SQS client.
|
|
37
|
+
*/
|
|
38
|
+
private getClient;
|
|
39
|
+
enqueue(message: JobMessage): Promise<EnqueueResult>;
|
|
40
|
+
enqueueAt(message: JobMessage, at: Date): Promise<EnqueueResult>;
|
|
41
|
+
enqueueIn(message: JobMessage, delay: Duration): Promise<EnqueueResult>;
|
|
42
|
+
receive(_options?: ReceiveOptions): Promise<ReceivedJob[]>;
|
|
43
|
+
ack(_job: ReceivedJob): Promise<void>;
|
|
44
|
+
nack(_job: ReceivedJob): Promise<void>;
|
|
45
|
+
private getQueueUrl;
|
|
46
|
+
private enqueueWithDelay;
|
|
47
|
+
private scheduleLongDelay;
|
|
48
|
+
private scheduleJobWithSelfReschedule;
|
|
49
|
+
private scheduleJobWithDynamo;
|
|
50
|
+
private getSchedulerClient;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=sqs-driver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqs-driver.d.ts","sourceRoot":"","sources":["../../../src/jobs/drivers/sqs-driver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,SAAS,IAAI,aAAa,EAC3B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EACV,QAAQ,EACR,aAAa,EACb,UAAU,EACV,WAAW,EACX,WAAW,EACX,cAAc,EACf,MAAM,aAAa,CAAC;AAMrB,MAAM,WAAW,eAAe;IAC9B,iBAAiB;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,yBAAyB;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uCAAuC;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,GAAG,UAAU,CAAC;IACnD,yCAAyC;IACzC,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED;;GAEG;AACH,qBAAa,cAAe,YAAW,WAAW;IAKpC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJnC,QAAQ,CAAC,IAAI,SAAS;IACtB,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,sBAAsB,CAAiC;gBAElC,MAAM,EAAE,eAAe;IAMpD;;OAEG;YACW,SAAS;IAWjB,OAAO,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC;IAqCpD,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC;IAWhE,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,aAAa,CAAC;IASvE,OAAO,CAAC,QAAQ,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAI1D,GAAG,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrC,IAAI,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5C,OAAO,CAAC,WAAW;YASL,gBAAgB;YAyChB,iBAAiB;YASjB,6BAA6B;YAyB7B,qBAAqB;YAgCrB,kBAAkB;CAqBjC"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import { MAX_SQS_DELAY_SECONDS, RUN_AT_METADATA_KEY } from '../schedule-constants.js';
|
|
2
|
+
import { durationToSeconds, generateJobId } from '../utils.js';
|
|
3
|
+
/**
|
|
4
|
+
* AWS SQS queue driver (Phase 1: enqueue only).
|
|
5
|
+
*/
|
|
6
|
+
export class SQSQueueDriver {
|
|
7
|
+
config;
|
|
8
|
+
name = 'sqs';
|
|
9
|
+
client = null;
|
|
10
|
+
schedulerClientPromise = null;
|
|
11
|
+
constructor(config) {
|
|
12
|
+
this.config = config;
|
|
13
|
+
if (config.client) {
|
|
14
|
+
this.client = config.client;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Lazily initialize the SQS client.
|
|
19
|
+
*/
|
|
20
|
+
async getClient() {
|
|
21
|
+
if (!this.client) {
|
|
22
|
+
const { SQSClient } = await import('@aws-sdk/client-sqs');
|
|
23
|
+
this.client = new SQSClient({
|
|
24
|
+
region: this.config.region,
|
|
25
|
+
...(this.config.endpoint && { endpoint: this.config.endpoint }),
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return this.client;
|
|
29
|
+
}
|
|
30
|
+
async enqueue(message) {
|
|
31
|
+
const client = await this.getClient();
|
|
32
|
+
const { SendMessageCommand } = await import('@aws-sdk/client-sqs');
|
|
33
|
+
const queueUrl = this.getQueueUrl(message.queue);
|
|
34
|
+
const jobId = message.jobId ?? generateJobId();
|
|
35
|
+
const isFifo = queueUrl.endsWith('.fifo');
|
|
36
|
+
const command = new SendMessageCommand({
|
|
37
|
+
QueueUrl: queueUrl,
|
|
38
|
+
MessageBody: JSON.stringify({
|
|
39
|
+
jobName: message.jobName,
|
|
40
|
+
payload: message.payload,
|
|
41
|
+
jobId,
|
|
42
|
+
metadata: message.metadata,
|
|
43
|
+
enqueuedAt: new Date().toISOString(),
|
|
44
|
+
}),
|
|
45
|
+
MessageAttributes: {
|
|
46
|
+
JobName: { DataType: 'String', StringValue: message.jobName },
|
|
47
|
+
},
|
|
48
|
+
...(isFifo && {
|
|
49
|
+
MessageGroupId: message.queue ?? message.jobName,
|
|
50
|
+
MessageDeduplicationId: jobId,
|
|
51
|
+
}),
|
|
52
|
+
});
|
|
53
|
+
const result = await client.send(command);
|
|
54
|
+
const messageId = result.MessageId;
|
|
55
|
+
if (!messageId) {
|
|
56
|
+
throw new Error('SQS did not return a message ID');
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
messageId,
|
|
60
|
+
jobId,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
async enqueueAt(message, at) {
|
|
64
|
+
const delaySeconds = Math.max(0, Math.floor((at.getTime() - Date.now()) / 1000));
|
|
65
|
+
if (delaySeconds <= 0) {
|
|
66
|
+
return this.enqueue(message);
|
|
67
|
+
}
|
|
68
|
+
if (delaySeconds <= MAX_SQS_DELAY_SECONDS) {
|
|
69
|
+
return this.enqueueWithDelay(message, delaySeconds);
|
|
70
|
+
}
|
|
71
|
+
return this.scheduleLongDelay(message, at);
|
|
72
|
+
}
|
|
73
|
+
async enqueueIn(message, delay) {
|
|
74
|
+
const delaySeconds = durationToSeconds(delay);
|
|
75
|
+
if (delaySeconds <= MAX_SQS_DELAY_SECONDS) {
|
|
76
|
+
return this.enqueueWithDelay(message, delaySeconds);
|
|
77
|
+
}
|
|
78
|
+
const at = new Date(Date.now() + delaySeconds * 1000);
|
|
79
|
+
return this.scheduleLongDelay(message, at);
|
|
80
|
+
}
|
|
81
|
+
async receive(_options) {
|
|
82
|
+
throw new Error('receive is not implemented for SQS driver');
|
|
83
|
+
}
|
|
84
|
+
async ack(_job) {
|
|
85
|
+
throw new Error('ack is not implemented for SQS driver');
|
|
86
|
+
}
|
|
87
|
+
async nack(_job) {
|
|
88
|
+
throw new Error('nack is not implemented for SQS driver');
|
|
89
|
+
}
|
|
90
|
+
getQueueUrl(queue) {
|
|
91
|
+
const queueName = queue ?? this.config.defaultQueue ?? 'default';
|
|
92
|
+
const queueUrl = this.config.queues[queueName];
|
|
93
|
+
if (!queueUrl) {
|
|
94
|
+
throw new Error(`Queue "${queueName}" is not configured for SQS driver`);
|
|
95
|
+
}
|
|
96
|
+
return queueUrl;
|
|
97
|
+
}
|
|
98
|
+
async enqueueWithDelay(message, delaySeconds) {
|
|
99
|
+
const client = await this.getClient();
|
|
100
|
+
const { SendMessageCommand } = await import('@aws-sdk/client-sqs');
|
|
101
|
+
const queueUrl = this.getQueueUrl(message.queue);
|
|
102
|
+
const jobId = message.jobId ?? generateJobId();
|
|
103
|
+
const isFifo = queueUrl.endsWith('.fifo');
|
|
104
|
+
const command = new SendMessageCommand({
|
|
105
|
+
QueueUrl: queueUrl,
|
|
106
|
+
MessageBody: JSON.stringify({
|
|
107
|
+
jobName: message.jobName,
|
|
108
|
+
payload: message.payload,
|
|
109
|
+
jobId,
|
|
110
|
+
metadata: message.metadata,
|
|
111
|
+
enqueuedAt: new Date().toISOString(),
|
|
112
|
+
}),
|
|
113
|
+
DelaySeconds: Math.min(MAX_SQS_DELAY_SECONDS, Math.max(0, Math.floor(delaySeconds))),
|
|
114
|
+
MessageAttributes: {
|
|
115
|
+
JobName: { DataType: 'String', StringValue: message.jobName },
|
|
116
|
+
},
|
|
117
|
+
...(isFifo && {
|
|
118
|
+
MessageGroupId: message.queue ?? message.jobName,
|
|
119
|
+
MessageDeduplicationId: jobId,
|
|
120
|
+
}),
|
|
121
|
+
});
|
|
122
|
+
const result = await client.send(command);
|
|
123
|
+
const messageId = result.MessageId;
|
|
124
|
+
if (!messageId) {
|
|
125
|
+
throw new Error('SQS did not return a message ID');
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
messageId,
|
|
129
|
+
jobId,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
async scheduleLongDelay(message, at) {
|
|
133
|
+
const strategy = this.config.longDelayStrategy ?? 'self-reschedule';
|
|
134
|
+
if (strategy === 'dynamodb') {
|
|
135
|
+
return this.scheduleJobWithDynamo(message, at);
|
|
136
|
+
}
|
|
137
|
+
return this.scheduleJobWithSelfReschedule(message, at);
|
|
138
|
+
}
|
|
139
|
+
async scheduleJobWithSelfReschedule(message, at) {
|
|
140
|
+
const jobId = message.jobId ?? generateJobId();
|
|
141
|
+
const metadata = {
|
|
142
|
+
...message.metadata,
|
|
143
|
+
[RUN_AT_METADATA_KEY]: at.toISOString(),
|
|
144
|
+
};
|
|
145
|
+
const delaySeconds = Math.max(1, Math.min(MAX_SQS_DELAY_SECONDS, Math.floor((at.getTime() - Date.now()) / 1000)));
|
|
146
|
+
return this.enqueueWithDelay({
|
|
147
|
+
...message,
|
|
148
|
+
jobId,
|
|
149
|
+
metadata,
|
|
150
|
+
}, delaySeconds);
|
|
151
|
+
}
|
|
152
|
+
async scheduleJobWithDynamo(message, at) {
|
|
153
|
+
if (!this.config.schedulerTable) {
|
|
154
|
+
throw new Error('schedulerTable is required for delays over 15 minutes when using dynamodb');
|
|
155
|
+
}
|
|
156
|
+
const { PutItemCommand } = await import('@aws-sdk/client-dynamodb');
|
|
157
|
+
const ddb = await this.getSchedulerClient();
|
|
158
|
+
const jobId = message.jobId ?? generateJobId();
|
|
159
|
+
const partition = `SCHEDULED#${at.toISOString().slice(0, 16)}`;
|
|
160
|
+
await ddb.send(new PutItemCommand({
|
|
161
|
+
TableName: this.config.schedulerTable,
|
|
162
|
+
Item: {
|
|
163
|
+
pk: { S: partition },
|
|
164
|
+
sk: { S: jobId },
|
|
165
|
+
jobName: { S: message.jobName },
|
|
166
|
+
payload: { S: JSON.stringify(message.payload) },
|
|
167
|
+
queue: { S: message.queue ?? this.config.defaultQueue ?? 'default' },
|
|
168
|
+
scheduledAt: { S: at.toISOString() },
|
|
169
|
+
ttl: { N: String(Math.floor(at.getTime() / 1000) + 86400) },
|
|
170
|
+
},
|
|
171
|
+
}));
|
|
172
|
+
return {
|
|
173
|
+
messageId: jobId,
|
|
174
|
+
jobId,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
async getSchedulerClient() {
|
|
178
|
+
if (this.schedulerClientPromise) {
|
|
179
|
+
return (await this.schedulerClientPromise);
|
|
180
|
+
}
|
|
181
|
+
this.schedulerClientPromise = (async () => {
|
|
182
|
+
const { DynamoDBClient } = await import('@aws-sdk/client-dynamodb');
|
|
183
|
+
return new DynamoDBClient({
|
|
184
|
+
region: this.config.region,
|
|
185
|
+
...(this.config.endpoint && { endpoint: this.config.endpoint }),
|
|
186
|
+
});
|
|
187
|
+
})();
|
|
188
|
+
return (await this.schedulerClientPromise);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=sqs-driver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqs-driver.js","sourceRoot":"","sources":["../../../src/jobs/drivers/sqs-driver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { BaseIssue } from 'valibot';
|
|
2
|
+
/**
|
|
3
|
+
* Indicates a job should not be retried.
|
|
4
|
+
*/
|
|
5
|
+
export declare class PermanentJobError extends Error {
|
|
6
|
+
constructor(message: string);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Thrown when a job payload exceeds the allowed size.
|
|
10
|
+
*/
|
|
11
|
+
export declare class PayloadTooLargeError extends Error {
|
|
12
|
+
readonly actualSize: number;
|
|
13
|
+
readonly maxSize: number;
|
|
14
|
+
constructor(actualSize: number, maxSize: number);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Thrown when payload validation fails against the job schema.
|
|
18
|
+
*/
|
|
19
|
+
export declare class InvalidJobPayloadError extends Error {
|
|
20
|
+
readonly jobName: string;
|
|
21
|
+
readonly issues: BaseIssue<unknown>[];
|
|
22
|
+
constructor(jobName: string, issues: BaseIssue<unknown>[]);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Indicates a transient failure that should be retried.
|
|
26
|
+
* Optionally carries a retry-after duration.
|
|
27
|
+
*/
|
|
28
|
+
export declare class TransientJobError extends Error {
|
|
29
|
+
readonly retryAfter?: import('./types.js').Duration;
|
|
30
|
+
constructor(message: string, retryAfter?: import('./types.js').Duration);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Thrown when attempting to enqueue a duplicate job (uniqueness constraint).
|
|
34
|
+
*/
|
|
35
|
+
export declare class DuplicateJobError extends Error {
|
|
36
|
+
readonly jobName: string;
|
|
37
|
+
readonly dedupeKey: string;
|
|
38
|
+
constructor(jobName: string, dedupeKey: string);
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/jobs/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;gBAC9B,OAAO,EAAE,MAAM;CAI5B;AAED;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;gBAEb,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAUhD;AAED;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;gBAE1B,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE;CAM1D;AAED;;;GAGG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,YAAY,EAAE,QAAQ,CAAC;gBAExC,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,OAAO,YAAY,EAAE,QAAQ;CAKxE;AAED;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;gBAEf,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;CAM/C"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Indicates a job should not be retried.
|
|
3
|
+
*/
|
|
4
|
+
export class PermanentJobError extends Error {
|
|
5
|
+
constructor(message) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = 'PermanentJobError';
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Thrown when a job payload exceeds the allowed size.
|
|
12
|
+
*/
|
|
13
|
+
export class PayloadTooLargeError extends Error {
|
|
14
|
+
actualSize;
|
|
15
|
+
maxSize;
|
|
16
|
+
constructor(actualSize, maxSize) {
|
|
17
|
+
super(`Job payload size (${Math.round(actualSize / 1024)}KB) exceeds SQS limit (${Math.round(maxSize / 1024)}KB). Consider storing large data externally and passing a reference.`);
|
|
18
|
+
this.name = 'PayloadTooLargeError';
|
|
19
|
+
this.actualSize = actualSize;
|
|
20
|
+
this.maxSize = maxSize;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Thrown when payload validation fails against the job schema.
|
|
25
|
+
*/
|
|
26
|
+
export class InvalidJobPayloadError extends Error {
|
|
27
|
+
jobName;
|
|
28
|
+
issues;
|
|
29
|
+
constructor(jobName, issues) {
|
|
30
|
+
super(`Invalid payload for job "${jobName}"`);
|
|
31
|
+
this.name = 'InvalidJobPayloadError';
|
|
32
|
+
this.jobName = jobName;
|
|
33
|
+
this.issues = issues;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Indicates a transient failure that should be retried.
|
|
38
|
+
* Optionally carries a retry-after duration.
|
|
39
|
+
*/
|
|
40
|
+
export class TransientJobError extends Error {
|
|
41
|
+
retryAfter;
|
|
42
|
+
constructor(message, retryAfter) {
|
|
43
|
+
super(message);
|
|
44
|
+
this.name = 'TransientJobError';
|
|
45
|
+
this.retryAfter = retryAfter;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Thrown when attempting to enqueue a duplicate job (uniqueness constraint).
|
|
50
|
+
*/
|
|
51
|
+
export class DuplicateJobError extends Error {
|
|
52
|
+
jobName;
|
|
53
|
+
dedupeKey;
|
|
54
|
+
constructor(jobName, dedupeKey) {
|
|
55
|
+
super(`Duplicate job rejected: "${jobName}" with key "${dedupeKey}"`);
|
|
56
|
+
this.name = 'DuplicateJobError';
|
|
57
|
+
this.jobName = jobName;
|
|
58
|
+
this.dedupeKey = dedupeKey;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/jobs/errors.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAC1C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IACpC,UAAU,CAAS;IACnB,OAAO,CAAS;IAEzB,YAAY,UAAkB,EAAE,OAAe;QAC7C,KAAK,CACH,qBAAqB,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,0BAA0B,IAAI,CAAC,KAAK,CACpF,OAAO,GAAG,IAAI,CACf,sEAAsE,CACxE,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;QACnC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IACtC,OAAO,CAAS;IAChB,MAAM,CAAuB;IAEtC,YAAY,OAAe,EAAE,MAA4B;QACvD,KAAK,CAAC,4BAA4B,OAAO,GAAG,CAAC,CAAC;QAC9C,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IACjC,UAAU,CAAiC;IAEpD,YAAY,OAAe,EAAE,UAA0C;QACrE,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;QAChC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IACjC,OAAO,CAAS;IAChB,SAAS,CAAS;IAE3B,YAAY,OAAe,EAAE,SAAiB;QAC5C,KAAK,CAAC,4BAA4B,OAAO,eAAe,SAAS,GAAG,CAAC,CAAC;QACtE,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;QAChC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;CACF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { defineJob } from './define-job.js';
|
|
2
|
+
export { type MockEnqueuedJob, MockQueueDriver } from './drivers/mock-driver.js';
|
|
3
|
+
export { type SQSDriverConfig, SQSQueueDriver } from './drivers/sqs-driver.js';
|
|
4
|
+
export { DuplicateJobError, InvalidJobPayloadError, PayloadTooLargeError, PermanentJobError, TransientJobError, } from './errors.js';
|
|
5
|
+
export { createJobRegistry, JobRegistry } from './job-registry.js';
|
|
6
|
+
export { JobService, type JobServiceConfig, type JobServiceHooks, } from './job-service.js';
|
|
7
|
+
export { definePeriodicJob } from './periodic-job.js';
|
|
8
|
+
export { createSchedulerHandler, type SchedulerConfig } from './scheduler.js';
|
|
9
|
+
export type { Duration, EnqueueResult, JobContext, JobDefinition, JobHandler, JobMessage, QueueDriver, ReceivedJob, ReceiveOptions, RetryConfig, } from './types.js';
|
|
10
|
+
export { bootstrapWorker } from './worker.js';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/jobs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,KAAK,eAAe,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACjF,OAAO,EAAE,KAAK,eAAe,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC/E,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EACL,UAAU,EACV,KAAK,gBAAgB,EACrB,KAAK,eAAe,GACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC9E,YAAY,EACV,QAAQ,EACR,aAAa,EACb,UAAU,EACV,aAAa,EACb,UAAU,EACV,UAAU,EACV,WAAW,EACX,WAAW,EACX,cAAc,EACd,WAAW,GACZ,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { defineJob } from './define-job.js';
|
|
2
|
+
export { MockQueueDriver } from './drivers/mock-driver.js';
|
|
3
|
+
export { SQSQueueDriver } from './drivers/sqs-driver.js';
|
|
4
|
+
export { DuplicateJobError, InvalidJobPayloadError, PayloadTooLargeError, PermanentJobError, TransientJobError, } from './errors.js';
|
|
5
|
+
export { createJobRegistry, JobRegistry } from './job-registry.js';
|
|
6
|
+
export { JobService, } from './job-service.js';
|
|
7
|
+
export { definePeriodicJob } from './periodic-job.js';
|
|
8
|
+
export { createSchedulerHandler } from './scheduler.js';
|
|
9
|
+
export { bootstrapWorker } from './worker.js';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/jobs/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAwB,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACjF,OAAO,EAAwB,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC/E,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EACL,UAAU,GAGX,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAwB,MAAM,gBAAgB,CAAC;AAa9E,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { JobDefinition } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Registry for job definitions.
|
|
4
|
+
*/
|
|
5
|
+
export declare class JobRegistry {
|
|
6
|
+
private readonly jobs;
|
|
7
|
+
constructor(initialJobs?: JobDefinition<unknown>[]);
|
|
8
|
+
/**
|
|
9
|
+
* Register a job definition. Throws if a job with the same name already exists.
|
|
10
|
+
*/
|
|
11
|
+
register<TPayload>(job: JobDefinition<TPayload>): this;
|
|
12
|
+
/**
|
|
13
|
+
* Get a job by name.
|
|
14
|
+
*/
|
|
15
|
+
get<TPayload = unknown>(name: string): JobDefinition<TPayload> | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Get a job by name or throw if not found.
|
|
18
|
+
*/
|
|
19
|
+
getOrThrow<TPayload = unknown>(name: string): JobDefinition<TPayload>;
|
|
20
|
+
/**
|
|
21
|
+
* List all registered jobs.
|
|
22
|
+
*/
|
|
23
|
+
list(): JobDefinition<unknown>[];
|
|
24
|
+
/**
|
|
25
|
+
* Number of registered jobs.
|
|
26
|
+
*/
|
|
27
|
+
get size(): number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Convenience helper to build a registry from an array.
|
|
31
|
+
*/
|
|
32
|
+
export declare function createJobRegistry(jobs?: JobDefinition<unknown>[]): JobRegistry;
|
|
33
|
+
//# sourceMappingURL=job-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-registry.d.ts","sourceRoot":"","sources":["../../src/jobs/job-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA6C;gBAEtD,WAAW,GAAE,aAAa,CAAC,OAAO,CAAC,EAAO;IAMtD;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE,aAAa,CAAC,QAAQ,CAAC,GAAG,IAAI;IAQtD;;OAEG;IACH,GAAG,CAAC,QAAQ,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,GAAG,SAAS;IAI1E;;OAEG;IACH,UAAU,CAAC,QAAQ,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC;IAQrE;;OAEG;IACH,IAAI,IAAI,aAAa,CAAC,OAAO,CAAC,EAAE;IAIhC;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;CACF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,GAAE,aAAa,CAAC,OAAO,CAAC,EAAO,GAAG,WAAW,CAElF"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registry for job definitions.
|
|
3
|
+
*/
|
|
4
|
+
export class JobRegistry {
|
|
5
|
+
jobs = new Map();
|
|
6
|
+
constructor(initialJobs = []) {
|
|
7
|
+
for (const job of initialJobs) {
|
|
8
|
+
this.register(job);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Register a job definition. Throws if a job with the same name already exists.
|
|
13
|
+
*/
|
|
14
|
+
register(job) {
|
|
15
|
+
if (this.jobs.has(job.name)) {
|
|
16
|
+
throw new Error(`Job "${job.name}" is already registered`);
|
|
17
|
+
}
|
|
18
|
+
this.jobs.set(job.name, job);
|
|
19
|
+
return this;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Get a job by name.
|
|
23
|
+
*/
|
|
24
|
+
get(name) {
|
|
25
|
+
return this.jobs.get(name);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Get a job by name or throw if not found.
|
|
29
|
+
*/
|
|
30
|
+
getOrThrow(name) {
|
|
31
|
+
const job = this.get(name);
|
|
32
|
+
if (!job) {
|
|
33
|
+
throw new Error(`Job "${name}" not found in registry`);
|
|
34
|
+
}
|
|
35
|
+
return job;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* List all registered jobs.
|
|
39
|
+
*/
|
|
40
|
+
list() {
|
|
41
|
+
return [...this.jobs.values()];
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Number of registered jobs.
|
|
45
|
+
*/
|
|
46
|
+
get size() {
|
|
47
|
+
return this.jobs.size;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Convenience helper to build a registry from an array.
|
|
52
|
+
*/
|
|
53
|
+
export function createJobRegistry(jobs = []) {
|
|
54
|
+
return new JobRegistry(jobs);
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=job-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-registry.js","sourceRoot":"","sources":["../../src/jobs/job-registry.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,OAAO,WAAW;IACL,IAAI,GAAG,IAAI,GAAG,EAAkC,CAAC;IAElE,YAAY,cAAwC,EAAE;QACpD,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;YAC9B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,QAAQ,CAAW,GAA4B;QAC7C,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,IAAI,yBAAyB,CAAC,CAAC;QAC7D,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,GAA6B,CAAC,CAAC;QACvD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,GAAG,CAAqB,IAAY;QAClC,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAwC,CAAC;IACpE,CAAC;IAED;;OAEG;IACH,UAAU,CAAqB,IAAY;QACzC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAW,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,yBAAyB,CAAC,CAAC;QACzD,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED;;OAEG;IACH,IAAI;QACF,OAAO,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACjC,CAAC;IAED;;OAEG;IACH,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IACxB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAiC,EAAE;IACnE,OAAO,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC"}
|