@pikku/queue-pg-boss 0.10.0 → 0.11.1
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/CHANGELOG.md +21 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/pg-boss-queue-service.d.ts +3 -11
- package/dist/pg-boss-queue-service.js +27 -19
- package/dist/pg-boss-queue-worker.d.ts +5 -13
- package/dist/pg-boss-queue-worker.js +5 -22
- package/dist/pg-boss-scheduler-service.d.ts +35 -0
- package/dist/pg-boss-scheduler-service.js +80 -0
- package/dist/pg-boss-service-factory.d.ts +37 -0
- package/dist/pg-boss-service-factory.js +71 -0
- package/dist/utils.d.ts +2 -2
- package/package.json +3 -3
- package/src/index.ts +2 -0
- package/src/pg-boss-queue-service.ts +34 -24
- package/src/pg-boss-queue-worker.ts +8 -26
- package/src/pg-boss-scheduler-service.ts +121 -0
- package/src/pg-boss-service-factory.ts +94 -0
- package/src/utils.ts +2 -2
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
## 0.11.0
|
|
2
|
+
|
|
3
|
+
## 0.11.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 4b811db: chore: updating all dependencies
|
|
8
|
+
- 06e1a31: breaking: change session services to wire services
|
|
9
|
+
- Updated dependencies [4b811db]
|
|
10
|
+
- Updated dependencies [e12a00c]
|
|
11
|
+
- Updated dependencies [4579434]
|
|
12
|
+
- Updated dependencies [28aeb7f]
|
|
13
|
+
- Updated dependencies [ce902b1]
|
|
14
|
+
- Updated dependencies [06e1a31]
|
|
15
|
+
- @pikku/core@0.11.1
|
|
16
|
+
|
|
17
|
+
### Minor Changes
|
|
18
|
+
|
|
19
|
+
- Add scheduler service implementation
|
|
20
|
+
- Add service factory for queue and scheduler creation
|
|
21
|
+
|
|
1
22
|
# @pikku/queue-pg-boss
|
|
2
23
|
|
|
3
24
|
## 0.10.0
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* PostgreSQL queue service for Pikku using pg-boss
|
|
5
5
|
* Provides job results, retries, priorities, and PostgreSQL-based queuing
|
|
6
6
|
*/
|
|
7
|
+
export { PgBossServiceFactory } from './pg-boss-service-factory.js';
|
|
7
8
|
export { PgBossQueueService } from './pg-boss-queue-service.js';
|
|
8
9
|
export { PgBossQueueWorkers } from './pg-boss-queue-worker.js';
|
|
10
|
+
export { PgBossSchedulerService } from './pg-boss-scheduler-service.js';
|
|
9
11
|
export type { QueueService, PikkuWorkerConfig, PikkuJobConfig, QueueJob, JobOptions, } from '@pikku/core/queue';
|
package/dist/index.js
CHANGED
|
@@ -4,5 +4,7 @@
|
|
|
4
4
|
* PostgreSQL queue service for Pikku using pg-boss
|
|
5
5
|
* Provides job results, retries, priorities, and PostgreSQL-based queuing
|
|
6
6
|
*/
|
|
7
|
+
export { PgBossServiceFactory } from './pg-boss-service-factory.js';
|
|
7
8
|
export { PgBossQueueService } from './pg-boss-queue-service.js';
|
|
8
9
|
export { PgBossQueueWorkers } from './pg-boss-queue-worker.js';
|
|
10
|
+
export { PgBossSchedulerService } from './pg-boss-scheduler-service.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import PgBoss from 'pg-boss';
|
|
1
|
+
import { PgBoss, Request as PgBossRequest } from 'pg-boss';
|
|
2
2
|
import type { QueueService, QueueJob, JobOptions } from '@pikku/core/queue';
|
|
3
|
-
export declare const mapPikkuJobToPgBoss: (options?: JobOptions) =>
|
|
3
|
+
export declare const mapPikkuJobToPgBoss: (options?: JobOptions) => PgBossRequest["options"];
|
|
4
4
|
/**
|
|
5
5
|
* pg-boss/PostgreSQL queue service implementation
|
|
6
6
|
* Supports job results, retries, and PostgreSQL-based queuing
|
|
@@ -9,11 +9,7 @@ export declare class PgBossQueueService implements QueueService {
|
|
|
9
9
|
readonly name = "pg-boss";
|
|
10
10
|
readonly supportsResults = true;
|
|
11
11
|
protected pgBoss: PgBoss;
|
|
12
|
-
constructor(
|
|
13
|
-
/**
|
|
14
|
-
* Initialize the pg-boss instance
|
|
15
|
-
*/
|
|
16
|
-
init(): Promise<void>;
|
|
12
|
+
constructor(pgBoss: PgBoss);
|
|
17
13
|
/**
|
|
18
14
|
* Add a job to the queue
|
|
19
15
|
*/
|
|
@@ -22,8 +18,4 @@ export declare class PgBossQueueService implements QueueService {
|
|
|
22
18
|
* Get job by ID
|
|
23
19
|
*/
|
|
24
20
|
getJob<T, R>(queueName: string, jobId: string): Promise<QueueJob<T, R> | null>;
|
|
25
|
-
/**
|
|
26
|
-
* Close the pg-boss connection
|
|
27
|
-
*/
|
|
28
|
-
close(): Promise<void>;
|
|
29
21
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import PgBoss from 'pg-boss';
|
|
2
1
|
import { mapPgBossJobToQueueJob } from './utils.js';
|
|
3
2
|
export const mapPikkuJobToPgBoss = (options) => {
|
|
4
3
|
const pgBossOptions = {};
|
|
@@ -11,6 +10,30 @@ export const mapPikkuJobToPgBoss = (options) => {
|
|
|
11
10
|
if (options?.jobId !== undefined) {
|
|
12
11
|
pgBossOptions.singletonKey = options.jobId;
|
|
13
12
|
}
|
|
13
|
+
// Map retry options
|
|
14
|
+
if (options?.attempts !== undefined) {
|
|
15
|
+
pgBossOptions.retryLimit = options.attempts - 1;
|
|
16
|
+
}
|
|
17
|
+
if (options?.backoff !== undefined) {
|
|
18
|
+
if (typeof options.backoff === 'string') {
|
|
19
|
+
// If backoff is a string, assume it's 'exponential' or 'fixed'
|
|
20
|
+
pgBossOptions.retryBackoff = options.backoff === 'exponential';
|
|
21
|
+
}
|
|
22
|
+
else if (typeof options.backoff === 'object') {
|
|
23
|
+
pgBossOptions.retryBackoff = options.backoff.type === 'exponential';
|
|
24
|
+
if (options.backoff.delay !== undefined) {
|
|
25
|
+
// pg-boss uses seconds, we use milliseconds
|
|
26
|
+
pgBossOptions.retryDelay = Math.floor(options.backoff.delay / 1000);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (options?.removeOnComplete !== undefined) {
|
|
31
|
+
pgBossOptions.onComplete = options.removeOnComplete === 0;
|
|
32
|
+
}
|
|
33
|
+
if (options?.removeOnFail !== undefined) {
|
|
34
|
+
// pg-boss doesn't have a direct equivalent, but we can track this for consistency
|
|
35
|
+
// Note: pg-boss keeps failed jobs by default
|
|
36
|
+
}
|
|
14
37
|
return pgBossOptions;
|
|
15
38
|
};
|
|
16
39
|
/**
|
|
@@ -21,23 +44,14 @@ export class PgBossQueueService {
|
|
|
21
44
|
name = 'pg-boss';
|
|
22
45
|
supportsResults = true;
|
|
23
46
|
pgBoss;
|
|
24
|
-
constructor(
|
|
25
|
-
|
|
26
|
-
// If a string is provided, treat it as the connection URL
|
|
27
|
-
optionsOrUrl = { connectionString: optionsOrUrl };
|
|
28
|
-
}
|
|
29
|
-
this.pgBoss = new PgBoss(optionsOrUrl);
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Initialize the pg-boss instance
|
|
33
|
-
*/
|
|
34
|
-
async init() {
|
|
35
|
-
await this.pgBoss.start();
|
|
47
|
+
constructor(pgBoss) {
|
|
48
|
+
this.pgBoss = pgBoss;
|
|
36
49
|
}
|
|
37
50
|
/**
|
|
38
51
|
* Add a job to the queue
|
|
39
52
|
*/
|
|
40
53
|
async add(queueName, data, options) {
|
|
54
|
+
await this.pgBoss.createQueue(queueName);
|
|
41
55
|
const jobId = await this.pgBoss.send(queueName, data, mapPikkuJobToPgBoss(options));
|
|
42
56
|
if (!jobId) {
|
|
43
57
|
throw new Error('Failed to create job');
|
|
@@ -54,10 +68,4 @@ export class PgBossQueueService {
|
|
|
54
68
|
}
|
|
55
69
|
return mapPgBossJobToQueueJob(job, this.pgBoss);
|
|
56
70
|
}
|
|
57
|
-
/**
|
|
58
|
-
* Close the pg-boss connection
|
|
59
|
-
*/
|
|
60
|
-
async close() {
|
|
61
|
-
await this.pgBoss.stop();
|
|
62
|
-
}
|
|
63
71
|
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import PgBoss from 'pg-boss';
|
|
1
|
+
import { PgBoss, type WorkOptions } from 'pg-boss';
|
|
2
2
|
import type { QueueWorkers, PikkuWorkerConfig, QueueConfigMapping, ConfigValidationResult } from '@pikku/core/queue';
|
|
3
|
-
import { CoreServices, CoreSingletonServices,
|
|
4
|
-
export declare const mapPikkuWorkerToPgBoss: (workerConfig?: PikkuWorkerConfig) =>
|
|
3
|
+
import { CoreServices, CoreSingletonServices, CreateWireServices } from '@pikku/core';
|
|
4
|
+
export declare const mapPikkuWorkerToPgBoss: (workerConfig?: PikkuWorkerConfig) => WorkOptions;
|
|
5
5
|
/**
|
|
6
6
|
* pg-boss/PostgreSQL queue worker implementation
|
|
7
7
|
* Supports job results, retries, and PostgreSQL-based queuing
|
|
8
8
|
*/
|
|
9
9
|
export declare class PgBossQueueWorkers implements QueueWorkers {
|
|
10
10
|
private singletonServices;
|
|
11
|
-
private
|
|
11
|
+
private createWireServices?;
|
|
12
12
|
readonly name = "pg-boss";
|
|
13
13
|
readonly supportsResults = true;
|
|
14
14
|
/**
|
|
@@ -18,17 +18,9 @@ export declare class PgBossQueueWorkers implements QueueWorkers {
|
|
|
18
18
|
readonly configMappings: QueueConfigMapping;
|
|
19
19
|
private pgBoss;
|
|
20
20
|
private activeWorkers;
|
|
21
|
-
constructor(
|
|
22
|
-
/**
|
|
23
|
-
* Initialize pg-boss
|
|
24
|
-
*/
|
|
25
|
-
init(): Promise<void>;
|
|
21
|
+
constructor(pgBoss: PgBoss, singletonServices: CoreSingletonServices, createWireServices?: CreateWireServices<CoreSingletonServices, CoreServices, any> | undefined);
|
|
26
22
|
/**
|
|
27
23
|
* Scan state and register all compatible processors
|
|
28
24
|
*/
|
|
29
25
|
registerQueues(): Promise<Record<string, ConfigValidationResult[]>>;
|
|
30
|
-
/**
|
|
31
|
-
* Close all workers and connections
|
|
32
|
-
*/
|
|
33
|
-
close(): Promise<void>;
|
|
34
26
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import PgBoss from 'pg-boss';
|
|
2
1
|
import { runQueueJob, registerQueueWorkers, QueueJobFailedError, QueueJobDiscardedError, } from '@pikku/core/queue';
|
|
3
2
|
import { mapPgBossJobToQueueJob } from './utils.js';
|
|
4
3
|
export const mapPikkuWorkerToPgBoss = (workerConfig) => {
|
|
@@ -17,7 +16,7 @@ export const mapPikkuWorkerToPgBoss = (workerConfig) => {
|
|
|
17
16
|
*/
|
|
18
17
|
export class PgBossQueueWorkers {
|
|
19
18
|
singletonServices;
|
|
20
|
-
|
|
19
|
+
createWireServices;
|
|
21
20
|
name = 'pg-boss';
|
|
22
21
|
supportsResults = true;
|
|
23
22
|
/**
|
|
@@ -84,20 +83,10 @@ export class PgBossQueueWorkers {
|
|
|
84
83
|
};
|
|
85
84
|
pgBoss;
|
|
86
85
|
activeWorkers = new Map();
|
|
87
|
-
constructor(
|
|
86
|
+
constructor(pgBoss, singletonServices, createWireServices) {
|
|
88
87
|
this.singletonServices = singletonServices;
|
|
89
|
-
this.
|
|
90
|
-
|
|
91
|
-
// If a string is provided, treat it as the connection string
|
|
92
|
-
options = { connectionString: options };
|
|
93
|
-
}
|
|
94
|
-
this.pgBoss = new PgBoss(options);
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Initialize pg-boss
|
|
98
|
-
*/
|
|
99
|
-
async init() {
|
|
100
|
-
await this.pgBoss.start();
|
|
88
|
+
this.createWireServices = createWireServices;
|
|
89
|
+
this.pgBoss = pgBoss;
|
|
101
90
|
}
|
|
102
91
|
/**
|
|
103
92
|
* Scan state and register all compatible processors
|
|
@@ -119,7 +108,7 @@ export class PgBossQueueWorkers {
|
|
|
119
108
|
try {
|
|
120
109
|
await runQueueJob({
|
|
121
110
|
singletonServices: this.singletonServices,
|
|
122
|
-
|
|
111
|
+
createWireServices: this.createWireServices,
|
|
123
112
|
job: mapPgBossJobToQueueJob(job, this.pgBoss),
|
|
124
113
|
});
|
|
125
114
|
}
|
|
@@ -139,10 +128,4 @@ export class PgBossQueueWorkers {
|
|
|
139
128
|
this.activeWorkers.set(queueName, workerId);
|
|
140
129
|
});
|
|
141
130
|
}
|
|
142
|
-
/**
|
|
143
|
-
* Close all workers and connections
|
|
144
|
-
*/
|
|
145
|
-
async close() {
|
|
146
|
-
await this.pgBoss.stop();
|
|
147
|
-
}
|
|
148
131
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { PgBoss } from 'pg-boss';
|
|
2
|
+
import { SchedulerService, ScheduledTaskInfo, ScheduledTaskSummary, CoreUserSession } from '@pikku/core';
|
|
3
|
+
/**
|
|
4
|
+
* pg-boss scheduler service implementation
|
|
5
|
+
* Uses pg-boss's schedule() API to store recurring jobs in PostgreSQL
|
|
6
|
+
*/
|
|
7
|
+
export declare class PgBossSchedulerService extends SchedulerService {
|
|
8
|
+
private pgBoss;
|
|
9
|
+
constructor(pgBoss: PgBoss);
|
|
10
|
+
/**
|
|
11
|
+
* Initialize - no-op as pg-boss is already initialized by factory
|
|
12
|
+
*/
|
|
13
|
+
init(): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* Schedule a one-off delayed RPC call
|
|
16
|
+
* Uses pg-boss send() with startAfter for one-time execution
|
|
17
|
+
*/
|
|
18
|
+
scheduleRPC(delay: number | string, rpcName: string, data?: any, session?: CoreUserSession): Promise<string>;
|
|
19
|
+
/**
|
|
20
|
+
* Unschedule (cancel) a task by ID
|
|
21
|
+
*/
|
|
22
|
+
unschedule(taskId: string): Promise<boolean>;
|
|
23
|
+
/**
|
|
24
|
+
* Get a scheduled task by ID with full details
|
|
25
|
+
*/
|
|
26
|
+
getTask(taskId: string): Promise<ScheduledTaskInfo | null>;
|
|
27
|
+
/**
|
|
28
|
+
* Get all scheduled tasks with minimal info
|
|
29
|
+
*/
|
|
30
|
+
getAllTasks(): Promise<ScheduledTaskSummary[]>;
|
|
31
|
+
/**
|
|
32
|
+
* Close - no-op as pg-boss lifecycle is managed by factory
|
|
33
|
+
*/
|
|
34
|
+
close(): Promise<void>;
|
|
35
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { SchedulerService, parseDurationString, } from '@pikku/core';
|
|
2
|
+
/**
|
|
3
|
+
* pg-boss scheduler service implementation
|
|
4
|
+
* Uses pg-boss's schedule() API to store recurring jobs in PostgreSQL
|
|
5
|
+
*/
|
|
6
|
+
export class PgBossSchedulerService extends SchedulerService {
|
|
7
|
+
pgBoss;
|
|
8
|
+
constructor(pgBoss) {
|
|
9
|
+
super();
|
|
10
|
+
this.pgBoss = pgBoss;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Initialize - no-op as pg-boss is already initialized by factory
|
|
14
|
+
*/
|
|
15
|
+
async init() {
|
|
16
|
+
// No-op - pg-boss is already initialized by factory
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Schedule a one-off delayed RPC call
|
|
20
|
+
* Uses pg-boss send() with startAfter for one-time execution
|
|
21
|
+
*/
|
|
22
|
+
async scheduleRPC(delay, rpcName, data, session) {
|
|
23
|
+
// Parse delay if it's a string
|
|
24
|
+
const delayMs = typeof delay === 'string' ? parseDurationString(delay) : delay;
|
|
25
|
+
const jobData = {
|
|
26
|
+
rpcName,
|
|
27
|
+
data,
|
|
28
|
+
session,
|
|
29
|
+
};
|
|
30
|
+
// Use send() with startAfter for one-off delayed execution
|
|
31
|
+
const taskId = await this.pgBoss.send('pikku-remote-internal-rpc', jobData, {
|
|
32
|
+
startAfter: new Date(Date.now() + delayMs),
|
|
33
|
+
singletonKey: `${rpcName}-${Date.now()}`, // Ensure uniqueness
|
|
34
|
+
});
|
|
35
|
+
if (!taskId) {
|
|
36
|
+
throw new Error('Failed to schedule RPC');
|
|
37
|
+
}
|
|
38
|
+
return taskId;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Unschedule (cancel) a task by ID
|
|
42
|
+
*/
|
|
43
|
+
async unschedule(taskId) {
|
|
44
|
+
await this.pgBoss.cancel('pikku-remote-internal-rpc', taskId);
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get a scheduled task by ID with full details
|
|
49
|
+
*/
|
|
50
|
+
async getTask(taskId) {
|
|
51
|
+
const job = await this.pgBoss.getJobById('pikku-remote-internal-rpc', taskId);
|
|
52
|
+
if (!job) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
const jobData = job.data;
|
|
56
|
+
return {
|
|
57
|
+
taskId: job.id,
|
|
58
|
+
rpcName: jobData.rpcName,
|
|
59
|
+
scheduledFor: job.startAfter || job.createdOn,
|
|
60
|
+
data: jobData.data,
|
|
61
|
+
session: jobData.session,
|
|
62
|
+
status: job.state,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Get all scheduled tasks with minimal info
|
|
67
|
+
*/
|
|
68
|
+
async getAllTasks() {
|
|
69
|
+
// pg-boss doesn't have a simple way to list all pending jobs
|
|
70
|
+
// This would require querying the database directly or maintaining a separate index
|
|
71
|
+
// For now, return empty array - can be implemented if needed
|
|
72
|
+
return [];
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Close - no-op as pg-boss lifecycle is managed by factory
|
|
76
|
+
*/
|
|
77
|
+
async close() {
|
|
78
|
+
// No-op - pg-boss lifecycle is managed by factory
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { PgBoss, type ConstructorOptions } from 'pg-boss';
|
|
2
|
+
import { PgBossQueueService } from './pg-boss-queue-service.js';
|
|
3
|
+
import { PgBossQueueWorkers } from './pg-boss-queue-worker.js';
|
|
4
|
+
import { PgBossSchedulerService } from './pg-boss-scheduler-service.js';
|
|
5
|
+
import type { CoreServices, CoreSingletonServices, CreateWireServices } from '@pikku/core';
|
|
6
|
+
/**
|
|
7
|
+
* Factory class for pg-boss services
|
|
8
|
+
* Manages a single PgBoss instance shared across queue, worker, and scheduler services
|
|
9
|
+
*/
|
|
10
|
+
export declare class PgBossServiceFactory {
|
|
11
|
+
private pgBoss;
|
|
12
|
+
private queueService?;
|
|
13
|
+
private queueWorkers?;
|
|
14
|
+
private schedulerService?;
|
|
15
|
+
private initialized;
|
|
16
|
+
constructor(optionsOrInstance: ConstructorOptions | string | PgBoss);
|
|
17
|
+
/**
|
|
18
|
+
* Initialize the pg-boss instance
|
|
19
|
+
*/
|
|
20
|
+
init(): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Get the queue service for publishing jobs
|
|
23
|
+
*/
|
|
24
|
+
getQueueService(): PgBossQueueService;
|
|
25
|
+
/**
|
|
26
|
+
* Get the queue workers for processing jobs
|
|
27
|
+
*/
|
|
28
|
+
getQueueWorkers(singletonServices: CoreSingletonServices, createWireServices?: CreateWireServices<CoreSingletonServices, CoreServices, any>): PgBossQueueWorkers;
|
|
29
|
+
/**
|
|
30
|
+
* Get the scheduler service for managing recurring tasks
|
|
31
|
+
*/
|
|
32
|
+
getSchedulerService(): PgBossSchedulerService;
|
|
33
|
+
/**
|
|
34
|
+
* Close all services and the pg-boss connection
|
|
35
|
+
*/
|
|
36
|
+
close(): Promise<void>;
|
|
37
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { PgBoss } from 'pg-boss';
|
|
2
|
+
import { PgBossQueueService } from './pg-boss-queue-service.js';
|
|
3
|
+
import { PgBossQueueWorkers } from './pg-boss-queue-worker.js';
|
|
4
|
+
import { PgBossSchedulerService } from './pg-boss-scheduler-service.js';
|
|
5
|
+
/**
|
|
6
|
+
* Factory class for pg-boss services
|
|
7
|
+
* Manages a single PgBoss instance shared across queue, worker, and scheduler services
|
|
8
|
+
*/
|
|
9
|
+
export class PgBossServiceFactory {
|
|
10
|
+
pgBoss;
|
|
11
|
+
queueService;
|
|
12
|
+
queueWorkers;
|
|
13
|
+
schedulerService;
|
|
14
|
+
initialized = false;
|
|
15
|
+
constructor(optionsOrInstance) {
|
|
16
|
+
if (optionsOrInstance instanceof PgBoss) {
|
|
17
|
+
this.pgBoss = optionsOrInstance;
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
const options = typeof optionsOrInstance === 'string'
|
|
21
|
+
? { connectionString: optionsOrInstance }
|
|
22
|
+
: optionsOrInstance;
|
|
23
|
+
this.pgBoss = new PgBoss(options);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Initialize the pg-boss instance
|
|
28
|
+
*/
|
|
29
|
+
async init() {
|
|
30
|
+
if (!this.initialized) {
|
|
31
|
+
await this.pgBoss.start();
|
|
32
|
+
this.initialized = true;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Get the queue service for publishing jobs
|
|
37
|
+
*/
|
|
38
|
+
getQueueService() {
|
|
39
|
+
if (!this.queueService) {
|
|
40
|
+
this.queueService = new PgBossQueueService(this.pgBoss);
|
|
41
|
+
}
|
|
42
|
+
return this.queueService;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Get the queue workers for processing jobs
|
|
46
|
+
*/
|
|
47
|
+
getQueueWorkers(singletonServices, createWireServices) {
|
|
48
|
+
if (!this.queueWorkers) {
|
|
49
|
+
this.queueWorkers = new PgBossQueueWorkers(this.pgBoss, singletonServices, createWireServices);
|
|
50
|
+
}
|
|
51
|
+
return this.queueWorkers;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get the scheduler service for managing recurring tasks
|
|
55
|
+
*/
|
|
56
|
+
getSchedulerService() {
|
|
57
|
+
if (!this.schedulerService) {
|
|
58
|
+
this.schedulerService = new PgBossSchedulerService(this.pgBoss);
|
|
59
|
+
}
|
|
60
|
+
return this.schedulerService;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Close all services and the pg-boss connection
|
|
64
|
+
*/
|
|
65
|
+
async close() {
|
|
66
|
+
if (this.initialized) {
|
|
67
|
+
await this.pgBoss.stop();
|
|
68
|
+
this.initialized = false;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { QueueJob } from '@pikku/core/queue';
|
|
2
|
-
import PgBoss from 'pg-boss';
|
|
2
|
+
import { PgBoss, type JobWithMetadata } from 'pg-boss';
|
|
3
3
|
/**
|
|
4
4
|
* Map pg-boss job to QueueJob interface
|
|
5
5
|
*/
|
|
6
|
-
export declare const mapPgBossJobToQueueJob: <In, Out>(pgBossJob:
|
|
6
|
+
export declare const mapPgBossJobToQueueJob: <In, Out>(pgBossJob: JobWithMetadata<In>, pgBossInstance: PgBoss) => QueueJob<In, Out>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pikku/queue-pg-boss",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"author": "yasser.fadl@gmail.com",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -13,10 +13,10 @@
|
|
|
13
13
|
"release": "npm run build && npm test"
|
|
14
14
|
},
|
|
15
15
|
"peerDependencies": {
|
|
16
|
-
"@pikku/core": "^0.
|
|
16
|
+
"@pikku/core": "^0.11.1"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"pg-boss": "^
|
|
19
|
+
"pg-boss": "^12.2.0"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"typescript": "^5.9"
|
package/src/index.ts
CHANGED
|
@@ -5,8 +5,10 @@
|
|
|
5
5
|
* Provides job results, retries, priorities, and PostgreSQL-based queuing
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
export { PgBossServiceFactory } from './pg-boss-service-factory.js'
|
|
8
9
|
export { PgBossQueueService } from './pg-boss-queue-service.js'
|
|
9
10
|
export { PgBossQueueWorkers } from './pg-boss-queue-worker.js'
|
|
11
|
+
export { PgBossSchedulerService } from './pg-boss-scheduler-service.js'
|
|
10
12
|
|
|
11
13
|
// Re-export core queue types for convenience
|
|
12
14
|
export type {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import PgBoss from 'pg-boss'
|
|
1
|
+
import { PgBoss, Request as PgBossRequest } from 'pg-boss'
|
|
2
2
|
import type { QueueService, QueueJob, JobOptions } from '@pikku/core/queue'
|
|
3
3
|
import { mapPgBossJobToQueueJob } from './utils.js'
|
|
4
4
|
|
|
5
5
|
export const mapPikkuJobToPgBoss = (
|
|
6
6
|
options?: JobOptions
|
|
7
|
-
):
|
|
8
|
-
const pgBossOptions:
|
|
7
|
+
): PgBossRequest['options'] => {
|
|
8
|
+
const pgBossOptions: any = {}
|
|
9
9
|
|
|
10
10
|
if (options?.priority !== undefined) {
|
|
11
11
|
pgBossOptions.priority = options.priority
|
|
@@ -19,7 +19,34 @@ export const mapPikkuJobToPgBoss = (
|
|
|
19
19
|
pgBossOptions.singletonKey = options.jobId
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
// Map retry options
|
|
23
|
+
if (options?.attempts !== undefined) {
|
|
24
|
+
pgBossOptions.retryLimit = options.attempts - 1
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (options?.backoff !== undefined) {
|
|
28
|
+
if (typeof options.backoff === 'string') {
|
|
29
|
+
// If backoff is a string, assume it's 'exponential' or 'fixed'
|
|
30
|
+
pgBossOptions.retryBackoff = options.backoff === 'exponential'
|
|
31
|
+
} else if (typeof options.backoff === 'object') {
|
|
32
|
+
pgBossOptions.retryBackoff = options.backoff.type === 'exponential'
|
|
33
|
+
if (options.backoff.delay !== undefined) {
|
|
34
|
+
// pg-boss uses seconds, we use milliseconds
|
|
35
|
+
pgBossOptions.retryDelay = Math.floor(options.backoff.delay / 1000)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (options?.removeOnComplete !== undefined) {
|
|
41
|
+
pgBossOptions.onComplete = options.removeOnComplete === 0
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (options?.removeOnFail !== undefined) {
|
|
45
|
+
// pg-boss doesn't have a direct equivalent, but we can track this for consistency
|
|
46
|
+
// Note: pg-boss keeps failed jobs by default
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return pgBossOptions as PgBossRequest['options']
|
|
23
50
|
}
|
|
24
51
|
|
|
25
52
|
/**
|
|
@@ -31,19 +58,8 @@ export class PgBossQueueService implements QueueService {
|
|
|
31
58
|
readonly supportsResults = true
|
|
32
59
|
protected pgBoss: PgBoss
|
|
33
60
|
|
|
34
|
-
constructor(
|
|
35
|
-
|
|
36
|
-
// If a string is provided, treat it as the connection URL
|
|
37
|
-
optionsOrUrl = { connectionString: optionsOrUrl }
|
|
38
|
-
}
|
|
39
|
-
this.pgBoss = new PgBoss(optionsOrUrl)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Initialize the pg-boss instance
|
|
44
|
-
*/
|
|
45
|
-
async init(): Promise<void> {
|
|
46
|
-
await this.pgBoss.start()
|
|
61
|
+
constructor(pgBoss: PgBoss) {
|
|
62
|
+
this.pgBoss = pgBoss
|
|
47
63
|
}
|
|
48
64
|
|
|
49
65
|
/**
|
|
@@ -54,6 +70,7 @@ export class PgBossQueueService implements QueueService {
|
|
|
54
70
|
data: In,
|
|
55
71
|
options?: JobOptions
|
|
56
72
|
): Promise<string> {
|
|
73
|
+
await this.pgBoss.createQueue(queueName)
|
|
57
74
|
const jobId = await this.pgBoss.send(
|
|
58
75
|
queueName,
|
|
59
76
|
data as any,
|
|
@@ -78,11 +95,4 @@ export class PgBossQueueService implements QueueService {
|
|
|
78
95
|
}
|
|
79
96
|
return mapPgBossJobToQueueJob<T, R>(job, this.pgBoss)
|
|
80
97
|
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Close the pg-boss connection
|
|
84
|
-
*/
|
|
85
|
-
async close(): Promise<void> {
|
|
86
|
-
await this.pgBoss.stop()
|
|
87
|
-
}
|
|
88
98
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import PgBoss from 'pg-boss'
|
|
1
|
+
import { PgBoss, type WorkOptions } from 'pg-boss'
|
|
2
2
|
import type {
|
|
3
3
|
QueueWorkers,
|
|
4
4
|
PikkuWorkerConfig,
|
|
@@ -14,14 +14,14 @@ import {
|
|
|
14
14
|
import {
|
|
15
15
|
CoreServices,
|
|
16
16
|
CoreSingletonServices,
|
|
17
|
-
|
|
17
|
+
CreateWireServices,
|
|
18
18
|
} from '@pikku/core'
|
|
19
19
|
import { mapPgBossJobToQueueJob } from './utils.js'
|
|
20
20
|
|
|
21
21
|
export const mapPikkuWorkerToPgBoss = (
|
|
22
22
|
workerConfig?: PikkuWorkerConfig
|
|
23
|
-
):
|
|
24
|
-
const workerOptions:
|
|
23
|
+
): WorkOptions => {
|
|
24
|
+
const workerOptions: WorkOptions = {}
|
|
25
25
|
|
|
26
26
|
if (workerConfig?.batchSize !== undefined) {
|
|
27
27
|
workerOptions.batchSize = workerConfig.batchSize
|
|
@@ -123,26 +123,15 @@ export class PgBossQueueWorkers implements QueueWorkers {
|
|
|
123
123
|
private activeWorkers = new Map<string, string>()
|
|
124
124
|
|
|
125
125
|
constructor(
|
|
126
|
-
|
|
126
|
+
pgBoss: PgBoss,
|
|
127
127
|
private singletonServices: CoreSingletonServices,
|
|
128
|
-
private
|
|
128
|
+
private createWireServices?: CreateWireServices<
|
|
129
129
|
CoreSingletonServices,
|
|
130
130
|
CoreServices,
|
|
131
131
|
any
|
|
132
132
|
>
|
|
133
133
|
) {
|
|
134
|
-
|
|
135
|
-
// If a string is provided, treat it as the connection string
|
|
136
|
-
options = { connectionString: options }
|
|
137
|
-
}
|
|
138
|
-
this.pgBoss = new PgBoss(options)
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Initialize pg-boss
|
|
143
|
-
*/
|
|
144
|
-
async init(): Promise<void> {
|
|
145
|
-
await this.pgBoss.start()
|
|
134
|
+
this.pgBoss = pgBoss
|
|
146
135
|
}
|
|
147
136
|
|
|
148
137
|
/**
|
|
@@ -173,7 +162,7 @@ export class PgBossQueueWorkers implements QueueWorkers {
|
|
|
173
162
|
try {
|
|
174
163
|
await runQueueJob({
|
|
175
164
|
singletonServices: this.singletonServices,
|
|
176
|
-
|
|
165
|
+
createWireServices: this.createWireServices,
|
|
177
166
|
job: mapPgBossJobToQueueJob(job, this.pgBoss),
|
|
178
167
|
})
|
|
179
168
|
} catch (error: unknown) {
|
|
@@ -195,11 +184,4 @@ export class PgBossQueueWorkers implements QueueWorkers {
|
|
|
195
184
|
}
|
|
196
185
|
)
|
|
197
186
|
}
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* Close all workers and connections
|
|
201
|
-
*/
|
|
202
|
-
async close(): Promise<void> {
|
|
203
|
-
await this.pgBoss.stop()
|
|
204
|
-
}
|
|
205
187
|
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { PgBoss } from 'pg-boss'
|
|
2
|
+
import {
|
|
3
|
+
SchedulerService,
|
|
4
|
+
ScheduledTaskInfo,
|
|
5
|
+
ScheduledTaskSummary,
|
|
6
|
+
CoreUserSession,
|
|
7
|
+
parseDurationString,
|
|
8
|
+
} from '@pikku/core'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Data stored in scheduled job
|
|
12
|
+
*/
|
|
13
|
+
interface ScheduledJobData {
|
|
14
|
+
rpcName: string
|
|
15
|
+
data?: any
|
|
16
|
+
session?: CoreUserSession
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* pg-boss scheduler service implementation
|
|
21
|
+
* Uses pg-boss's schedule() API to store recurring jobs in PostgreSQL
|
|
22
|
+
*/
|
|
23
|
+
export class PgBossSchedulerService extends SchedulerService {
|
|
24
|
+
constructor(private pgBoss: PgBoss) {
|
|
25
|
+
super()
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Initialize - no-op as pg-boss is already initialized by factory
|
|
30
|
+
*/
|
|
31
|
+
async init(): Promise<void> {
|
|
32
|
+
// No-op - pg-boss is already initialized by factory
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Schedule a one-off delayed RPC call
|
|
37
|
+
* Uses pg-boss send() with startAfter for one-time execution
|
|
38
|
+
*/
|
|
39
|
+
async scheduleRPC(
|
|
40
|
+
delay: number | string,
|
|
41
|
+
rpcName: string,
|
|
42
|
+
data?: any,
|
|
43
|
+
session?: CoreUserSession
|
|
44
|
+
): Promise<string> {
|
|
45
|
+
// Parse delay if it's a string
|
|
46
|
+
const delayMs =
|
|
47
|
+
typeof delay === 'string' ? parseDurationString(delay) : delay
|
|
48
|
+
|
|
49
|
+
const jobData: ScheduledJobData = {
|
|
50
|
+
rpcName,
|
|
51
|
+
data,
|
|
52
|
+
session,
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Use send() with startAfter for one-off delayed execution
|
|
56
|
+
const taskId = await this.pgBoss.send(
|
|
57
|
+
'pikku-remote-internal-rpc',
|
|
58
|
+
jobData,
|
|
59
|
+
{
|
|
60
|
+
startAfter: new Date(Date.now() + delayMs),
|
|
61
|
+
singletonKey: `${rpcName}-${Date.now()}`, // Ensure uniqueness
|
|
62
|
+
}
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
if (!taskId) {
|
|
66
|
+
throw new Error('Failed to schedule RPC')
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return taskId
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Unschedule (cancel) a task by ID
|
|
74
|
+
*/
|
|
75
|
+
async unschedule(taskId: string): Promise<boolean> {
|
|
76
|
+
await this.pgBoss.cancel('pikku-remote-internal-rpc', taskId)
|
|
77
|
+
return true
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Get a scheduled task by ID with full details
|
|
82
|
+
*/
|
|
83
|
+
async getTask(taskId: string): Promise<ScheduledTaskInfo | null> {
|
|
84
|
+
const job = await this.pgBoss.getJobById(
|
|
85
|
+
'pikku-remote-internal-rpc',
|
|
86
|
+
taskId
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
if (!job) {
|
|
90
|
+
return null
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const jobData = job.data as ScheduledJobData
|
|
94
|
+
|
|
95
|
+
return {
|
|
96
|
+
taskId: job.id,
|
|
97
|
+
rpcName: jobData.rpcName,
|
|
98
|
+
scheduledFor: job.startAfter || job.createdOn,
|
|
99
|
+
data: jobData.data,
|
|
100
|
+
session: jobData.session,
|
|
101
|
+
status: job.state as any,
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Get all scheduled tasks with minimal info
|
|
107
|
+
*/
|
|
108
|
+
async getAllTasks(): Promise<ScheduledTaskSummary[]> {
|
|
109
|
+
// pg-boss doesn't have a simple way to list all pending jobs
|
|
110
|
+
// This would require querying the database directly or maintaining a separate index
|
|
111
|
+
// For now, return empty array - can be implemented if needed
|
|
112
|
+
return []
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Close - no-op as pg-boss lifecycle is managed by factory
|
|
117
|
+
*/
|
|
118
|
+
async close(): Promise<void> {
|
|
119
|
+
// No-op - pg-boss lifecycle is managed by factory
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { PgBoss, type ConstructorOptions } from 'pg-boss'
|
|
2
|
+
import { PgBossQueueService } from './pg-boss-queue-service.js'
|
|
3
|
+
import { PgBossQueueWorkers } from './pg-boss-queue-worker.js'
|
|
4
|
+
import { PgBossSchedulerService } from './pg-boss-scheduler-service.js'
|
|
5
|
+
import type {
|
|
6
|
+
CoreServices,
|
|
7
|
+
CoreSingletonServices,
|
|
8
|
+
CreateWireServices,
|
|
9
|
+
} from '@pikku/core'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Factory class for pg-boss services
|
|
13
|
+
* Manages a single PgBoss instance shared across queue, worker, and scheduler services
|
|
14
|
+
*/
|
|
15
|
+
export class PgBossServiceFactory {
|
|
16
|
+
private pgBoss: PgBoss
|
|
17
|
+
private queueService?: PgBossQueueService
|
|
18
|
+
private queueWorkers?: PgBossQueueWorkers
|
|
19
|
+
private schedulerService?: PgBossSchedulerService
|
|
20
|
+
private initialized = false
|
|
21
|
+
|
|
22
|
+
constructor(optionsOrInstance: ConstructorOptions | string | PgBoss) {
|
|
23
|
+
if (optionsOrInstance instanceof PgBoss) {
|
|
24
|
+
this.pgBoss = optionsOrInstance
|
|
25
|
+
} else {
|
|
26
|
+
const options =
|
|
27
|
+
typeof optionsOrInstance === 'string'
|
|
28
|
+
? { connectionString: optionsOrInstance }
|
|
29
|
+
: optionsOrInstance
|
|
30
|
+
this.pgBoss = new PgBoss(options)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Initialize the pg-boss instance
|
|
36
|
+
*/
|
|
37
|
+
async init(): Promise<void> {
|
|
38
|
+
if (!this.initialized) {
|
|
39
|
+
await this.pgBoss.start()
|
|
40
|
+
this.initialized = true
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Get the queue service for publishing jobs
|
|
46
|
+
*/
|
|
47
|
+
getQueueService(): PgBossQueueService {
|
|
48
|
+
if (!this.queueService) {
|
|
49
|
+
this.queueService = new PgBossQueueService(this.pgBoss)
|
|
50
|
+
}
|
|
51
|
+
return this.queueService
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Get the queue workers for processing jobs
|
|
56
|
+
*/
|
|
57
|
+
getQueueWorkers(
|
|
58
|
+
singletonServices: CoreSingletonServices,
|
|
59
|
+
createWireServices?: CreateWireServices<
|
|
60
|
+
CoreSingletonServices,
|
|
61
|
+
CoreServices,
|
|
62
|
+
any
|
|
63
|
+
>
|
|
64
|
+
): PgBossQueueWorkers {
|
|
65
|
+
if (!this.queueWorkers) {
|
|
66
|
+
this.queueWorkers = new PgBossQueueWorkers(
|
|
67
|
+
this.pgBoss,
|
|
68
|
+
singletonServices,
|
|
69
|
+
createWireServices
|
|
70
|
+
)
|
|
71
|
+
}
|
|
72
|
+
return this.queueWorkers
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Get the scheduler service for managing recurring tasks
|
|
77
|
+
*/
|
|
78
|
+
getSchedulerService(): PgBossSchedulerService {
|
|
79
|
+
if (!this.schedulerService) {
|
|
80
|
+
this.schedulerService = new PgBossSchedulerService(this.pgBoss)
|
|
81
|
+
}
|
|
82
|
+
return this.schedulerService
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Close all services and the pg-boss connection
|
|
87
|
+
*/
|
|
88
|
+
async close(): Promise<void> {
|
|
89
|
+
if (this.initialized) {
|
|
90
|
+
await this.pgBoss.stop()
|
|
91
|
+
this.initialized = false
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
package/src/utils.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { QueueJob, QueueJobStatus } from '@pikku/core/queue'
|
|
2
|
-
import PgBoss from 'pg-boss'
|
|
2
|
+
import { PgBoss, type JobWithMetadata } from 'pg-boss'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Map pg-boss job state to our queue job status
|
|
@@ -26,7 +26,7 @@ const mapPgBossStateToStatus = (state: string): QueueJobStatus => {
|
|
|
26
26
|
* Map pg-boss job to QueueJob interface
|
|
27
27
|
*/
|
|
28
28
|
export const mapPgBossJobToQueueJob = <In, Out>(
|
|
29
|
-
pgBossJob:
|
|
29
|
+
pgBossJob: JobWithMetadata<In>,
|
|
30
30
|
pgBossInstance: PgBoss
|
|
31
31
|
): QueueJob<In, Out> => {
|
|
32
32
|
return {
|
package/tsconfig.tsbuildinfo
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["./src/index.ts","./src/pg-boss-queue-service.ts","./src/pg-boss-queue-worker.ts","./src/utils.ts"],"version":"5.9.3"}
|
|
1
|
+
{"root":["./src/index.ts","./src/pg-boss-queue-service.ts","./src/pg-boss-queue-worker.ts","./src/pg-boss-scheduler-service.ts","./src/pg-boss-service-factory.ts","./src/utils.ts"],"version":"5.9.3"}
|