dt-common-device 7.6.12 → 7.6.14
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/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/pms/webhookQueue/interfaces/IWebhookQueue.d.ts +26 -0
- package/dist/pms/webhookQueue/services/WebhookQueueService.d.ts +3 -1
- package/dist/pms/webhookQueue/services/WebhookQueueService.js +55 -32
- package/dist/webhookQueue/index.d.ts +2 -0
- package/dist/webhookQueue/index.js +18 -0
- package/dist/webhookQueue/interfaces/IWebhookQueue.d.ts +32 -0
- package/dist/webhookQueue/interfaces/IWebhookQueue.js +2 -0
- package/dist/webhookQueue/interfaces/index.d.ts +1 -0
- package/dist/webhookQueue/interfaces/index.js +17 -0
- package/dist/webhookQueue/services/WebhookQueueService.d.ts +41 -0
- package/dist/webhookQueue/services/WebhookQueueService.js +266 -0
- package/dist/webhookQueue/services/index.d.ts +1 -0
- package/dist/webhookQueue/services/index.js +17 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -60,4 +60,4 @@ Object.defineProperty(exports, "initialize", { enumerable: true, get: function (
|
|
|
60
60
|
Object.defineProperty(exports, "getConfig", { enumerable: true, get: function () { return config_1.getConfig; } });
|
|
61
61
|
Object.defineProperty(exports, "shutdown", { enumerable: true, get: function () { return config_1.shutdown; } });
|
|
62
62
|
//Export PMS Webhook Queue
|
|
63
|
-
__exportStar(require("./
|
|
63
|
+
__exportStar(require("./webhookQueue"), exports);
|
|
@@ -4,4 +4,30 @@ export interface IWebhookQueue {
|
|
|
4
4
|
* Add a webhook to the appropriate queue based on propertyId and pmsType
|
|
5
5
|
*/
|
|
6
6
|
addWebhookToQueue(propertyId: string, pmsType: string, webhookData: any, options?: IWebhookQueueOptions): Promise<string>;
|
|
7
|
+
/**
|
|
8
|
+
* Mark a webhook job as completed (processed successfully)
|
|
9
|
+
*/
|
|
10
|
+
markWebhookCompleted(propertyId: string, pmsType: string, jobId: string): Promise<void>;
|
|
11
|
+
/**
|
|
12
|
+
* Mark a webhook job as failed
|
|
13
|
+
*/
|
|
14
|
+
markWebhookFailed(propertyId: string, pmsType: string, jobId: string, error?: string): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Poll available webhook from ANY available webhook queue in Redis
|
|
17
|
+
*/
|
|
18
|
+
pollWebhookFromQueues(): Promise<{
|
|
19
|
+
jobId: string;
|
|
20
|
+
data: any;
|
|
21
|
+
propertyId: string;
|
|
22
|
+
pmsType: string;
|
|
23
|
+
queueName: string;
|
|
24
|
+
} | null>;
|
|
25
|
+
/**
|
|
26
|
+
* Get all available webhook queue names from Redis
|
|
27
|
+
*/
|
|
28
|
+
getAllQueueNames(): Promise<string[]>;
|
|
29
|
+
/**
|
|
30
|
+
* Get total waiting count across all webhook queues
|
|
31
|
+
*/
|
|
32
|
+
getTotalWaitingCount(): Promise<number>;
|
|
7
33
|
}
|
|
@@ -14,10 +14,12 @@ export declare class WebhookQueueService implements IWebhookQueue {
|
|
|
14
14
|
addWebhookToQueue(propertyId: string, pmsType: string, webhookData: any, options?: IWebhookQueueOptions): Promise<string>;
|
|
15
15
|
/**
|
|
16
16
|
* Mark a webhook job as completed (processed successfully)
|
|
17
|
+
* Note: Jobs are now removed immediately when polled, so this method is for logging purposes
|
|
17
18
|
*/
|
|
18
19
|
markWebhookCompleted(propertyId: string, pmsType: string, jobId: string): Promise<void>;
|
|
19
20
|
/**
|
|
20
21
|
* Mark a webhook job as failed
|
|
22
|
+
* Note: Jobs are now removed immediately when polled, so this method is for logging purposes
|
|
21
23
|
*/
|
|
22
24
|
markWebhookFailed(propertyId: string, pmsType: string, jobId: string, error?: string): Promise<void>;
|
|
23
25
|
/**
|
|
@@ -39,5 +41,5 @@ export declare class WebhookQueueService implements IWebhookQueue {
|
|
|
39
41
|
* Get total waiting count across all webhook queues
|
|
40
42
|
*/
|
|
41
43
|
getTotalWaitingCount(): Promise<number>;
|
|
42
|
-
static getOrCreateQueue(queueKey: string, queues: Map<string, any>): any
|
|
44
|
+
static getOrCreateQueue(queueKey: string, queues: Map<string, any>): Promise<any>;
|
|
43
45
|
}
|
|
@@ -1,4 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
2
18
|
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
3
19
|
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
4
20
|
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
@@ -33,6 +49,23 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
|
|
|
33
49
|
}
|
|
34
50
|
return useValue ? value : void 0;
|
|
35
51
|
};
|
|
52
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
53
|
+
var ownKeys = function(o) {
|
|
54
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
55
|
+
var ar = [];
|
|
56
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
57
|
+
return ar;
|
|
58
|
+
};
|
|
59
|
+
return ownKeys(o);
|
|
60
|
+
};
|
|
61
|
+
return function (mod) {
|
|
62
|
+
if (mod && mod.__esModule) return mod;
|
|
63
|
+
var result = {};
|
|
64
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
65
|
+
__setModuleDefault(result, mod);
|
|
66
|
+
return result;
|
|
67
|
+
};
|
|
68
|
+
})();
|
|
36
69
|
var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
|
|
37
70
|
if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
|
|
38
71
|
return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
|
|
@@ -64,7 +97,7 @@ let WebhookQueueService = (() => {
|
|
|
64
97
|
async addWebhookToQueue(propertyId, pmsType, webhookData, options) {
|
|
65
98
|
const queueName = this.generateQueueName(propertyId, pmsType);
|
|
66
99
|
// Get or create queue using the static method
|
|
67
|
-
const queue = WebhookQueueService.getOrCreateQueue(queueName, this.webhookQueues);
|
|
100
|
+
const queue = await WebhookQueueService.getOrCreateQueue(queueName, this.webhookQueues);
|
|
68
101
|
// Add job to queue immediately with 5 minute TTL
|
|
69
102
|
const job = await queue.add("webhook-job", {
|
|
70
103
|
propertyId,
|
|
@@ -80,33 +113,19 @@ let WebhookQueueService = (() => {
|
|
|
80
113
|
}
|
|
81
114
|
/**
|
|
82
115
|
* Mark a webhook job as completed (processed successfully)
|
|
116
|
+
* Note: Jobs are now removed immediately when polled, so this method is for logging purposes
|
|
83
117
|
*/
|
|
84
118
|
async markWebhookCompleted(propertyId, pmsType, jobId) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
throw new Error(`Queue ${queueName} does not exist`);
|
|
88
|
-
}
|
|
89
|
-
const queue = this.webhookQueues.get(queueName);
|
|
90
|
-
const job = await queue.getJob(jobId);
|
|
91
|
-
if (job) {
|
|
92
|
-
// Mark job as completed - it will be removed after TTL
|
|
93
|
-
await job.moveToCompleted();
|
|
94
|
-
}
|
|
119
|
+
// Jobs are removed immediately when polled, so just log completion
|
|
120
|
+
console.log(`Webhook job ${jobId} marked as completed for ${propertyId}_${pmsType}`);
|
|
95
121
|
}
|
|
96
122
|
/**
|
|
97
123
|
* Mark a webhook job as failed
|
|
124
|
+
* Note: Jobs are now removed immediately when polled, so this method is for logging purposes
|
|
98
125
|
*/
|
|
99
126
|
async markWebhookFailed(propertyId, pmsType, jobId, error) {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
throw new Error(`Queue ${queueName} does not exist`);
|
|
103
|
-
}
|
|
104
|
-
const queue = this.webhookQueues.get(queueName);
|
|
105
|
-
const job = await queue.getJob(jobId);
|
|
106
|
-
if (job) {
|
|
107
|
-
// Mark job as failed - it will be removed after TTL
|
|
108
|
-
await job.moveToFailed(new Error(error || "Job processing failed"));
|
|
109
|
-
}
|
|
127
|
+
// Jobs are removed immediately when polled, so just log failure
|
|
128
|
+
console.error(`Webhook job ${jobId} marked as failed for ${propertyId}_${pmsType}: ${error || "Unknown error"}`);
|
|
110
129
|
}
|
|
111
130
|
/**
|
|
112
131
|
* Poll available webhook from ANY available webhook queue in Redis
|
|
@@ -129,18 +148,19 @@ let WebhookQueueService = (() => {
|
|
|
129
148
|
try {
|
|
130
149
|
// Create queue instance if not exists locally
|
|
131
150
|
if (!this.webhookQueues.has(queueName)) {
|
|
132
|
-
const { Queue } = require("bullmq");
|
|
151
|
+
const { Queue } = await Promise.resolve().then(() => __importStar(require("bullmq")));
|
|
133
152
|
const queue = new Queue(queueName, {
|
|
134
153
|
connection: (0, redis_1.getRedisClient)(),
|
|
135
154
|
});
|
|
136
155
|
this.webhookQueues.set(queueName, queue);
|
|
137
156
|
}
|
|
138
157
|
const queue = this.webhookQueues.get(queueName);
|
|
158
|
+
// Get waiting jobs and take the first one
|
|
139
159
|
const waitingJobs = await queue.getWaiting(0, 1);
|
|
140
160
|
if (waitingJobs.length > 0) {
|
|
141
161
|
const job = waitingJobs[0];
|
|
142
|
-
//
|
|
143
|
-
await job.
|
|
162
|
+
// Remove the job from the queue to prevent duplicate processing
|
|
163
|
+
await job.remove();
|
|
144
164
|
// Extract propertyId and pmsType from queue name
|
|
145
165
|
const parts = queueName.split("_");
|
|
146
166
|
const propertyId = parts[0];
|
|
@@ -203,7 +223,7 @@ let WebhookQueueService = (() => {
|
|
|
203
223
|
try {
|
|
204
224
|
// Create queue instance if not exists locally
|
|
205
225
|
if (!this.webhookQueues.has(queueName)) {
|
|
206
|
-
const { Queue } = require("bullmq");
|
|
226
|
+
const { Queue } = await Promise.resolve().then(() => __importStar(require("bullmq")));
|
|
207
227
|
const queue = new Queue(queueName, {
|
|
208
228
|
connection: (0, redis_1.getRedisClient)(),
|
|
209
229
|
});
|
|
@@ -225,13 +245,16 @@ let WebhookQueueService = (() => {
|
|
|
225
245
|
return 0;
|
|
226
246
|
}
|
|
227
247
|
}
|
|
228
|
-
static getOrCreateQueue(queueKey, queues) {
|
|
229
|
-
|
|
230
|
-
queues
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
248
|
+
static async getOrCreateQueue(queueKey, queues) {
|
|
249
|
+
if (queues.has(queueKey)) {
|
|
250
|
+
return queues.get(queueKey);
|
|
251
|
+
}
|
|
252
|
+
const { Queue } = await Promise.resolve().then(() => __importStar(require("bullmq")));
|
|
253
|
+
const queue = new Queue(queueKey, {
|
|
254
|
+
connection: (0, redis_1.getRedisClient)(),
|
|
255
|
+
});
|
|
256
|
+
queues.set(queueKey, queue);
|
|
257
|
+
return queue;
|
|
235
258
|
}
|
|
236
259
|
};
|
|
237
260
|
__setFunctionName(_classThis, "WebhookQueueService");
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./services"), exports);
|
|
18
|
+
__exportStar(require("./interfaces"), exports);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface IWebhookQueue {
|
|
2
|
+
/**
|
|
3
|
+
* Add a webhook to the appropriate queue based on propertyId and pmsType
|
|
4
|
+
*/
|
|
5
|
+
addWebhookToQueue(propertyId: string, pmsType: string, webhookData: any, options?: any): Promise<string>;
|
|
6
|
+
/**
|
|
7
|
+
* Mark a webhook job as completed (processed successfully)
|
|
8
|
+
*/
|
|
9
|
+
markWebhookCompleted(propertyId: string, pmsType: string, jobId: string): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Mark a webhook job as failed
|
|
12
|
+
*/
|
|
13
|
+
markWebhookFailed(propertyId: string, pmsType: string, jobId: string, error?: string): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* Poll available webhook from ANY available webhook queue in Redis
|
|
16
|
+
*/
|
|
17
|
+
pollWebhookFromQueues(): Promise<{
|
|
18
|
+
jobId: string;
|
|
19
|
+
data: any;
|
|
20
|
+
propertyId: string;
|
|
21
|
+
pmsType: string;
|
|
22
|
+
queueName: string;
|
|
23
|
+
} | null>;
|
|
24
|
+
/**
|
|
25
|
+
* Get all available webhook queue names from Redis
|
|
26
|
+
*/
|
|
27
|
+
getAllQueueNames(): Promise<string[]>;
|
|
28
|
+
/**
|
|
29
|
+
* Get total waiting count across all webhook queues
|
|
30
|
+
*/
|
|
31
|
+
getTotalWaitingCount(): Promise<number>;
|
|
32
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./IWebhookQueue";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./IWebhookQueue"), exports);
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { IWebhookQueue } from "../interfaces/IWebhookQueue";
|
|
2
|
+
export declare class WebhookQueueService implements IWebhookQueue {
|
|
3
|
+
private readonly webhookQueues;
|
|
4
|
+
constructor();
|
|
5
|
+
private generateQueueName;
|
|
6
|
+
/**
|
|
7
|
+
* Add a webhook to the appropriate queue based on propertyId and pmsType
|
|
8
|
+
* Creates queue if it doesn't exist
|
|
9
|
+
*/
|
|
10
|
+
addWebhookToQueue(propertyId: string, pmsType: string, webhookData: any, options?: any): Promise<string>;
|
|
11
|
+
/**
|
|
12
|
+
* Mark a webhook job as completed (processed successfully)
|
|
13
|
+
* Note: Jobs are now removed immediately when polled, so this method is for logging purposes
|
|
14
|
+
*/
|
|
15
|
+
markWebhookCompleted(propertyId: string, pmsType: string, jobId: string): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Mark a webhook job as failed
|
|
18
|
+
* Note: Jobs are now removed immediately when polled, so this method is for logging purposes
|
|
19
|
+
*/
|
|
20
|
+
markWebhookFailed(propertyId: string, pmsType: string, jobId: string, error?: string): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Poll available webhook from ANY available webhook queue in Redis
|
|
23
|
+
* This method will discover all queues in Redis and filter only webhook queues
|
|
24
|
+
*/
|
|
25
|
+
pollWebhookFromQueues(): Promise<{
|
|
26
|
+
jobId: string;
|
|
27
|
+
data: any;
|
|
28
|
+
propertyId: string;
|
|
29
|
+
pmsType: string;
|
|
30
|
+
queueName: string;
|
|
31
|
+
} | null>;
|
|
32
|
+
/**
|
|
33
|
+
* Get all available webhook queue names from Redis
|
|
34
|
+
*/
|
|
35
|
+
getAllQueueNames(): Promise<string[]>;
|
|
36
|
+
/**
|
|
37
|
+
* Get total waiting count across all webhook queues
|
|
38
|
+
*/
|
|
39
|
+
getTotalWaitingCount(): Promise<number>;
|
|
40
|
+
static getOrCreateQueue(queueKey: string, queues: Map<string, any>): Promise<any>;
|
|
41
|
+
}
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
19
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
20
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
21
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
22
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
23
|
+
var _, done = false;
|
|
24
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
25
|
+
var context = {};
|
|
26
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
27
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
28
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
29
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
30
|
+
if (kind === "accessor") {
|
|
31
|
+
if (result === void 0) continue;
|
|
32
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
33
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
34
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
35
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
36
|
+
}
|
|
37
|
+
else if (_ = accept(result)) {
|
|
38
|
+
if (kind === "field") initializers.unshift(_);
|
|
39
|
+
else descriptor[key] = _;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
43
|
+
done = true;
|
|
44
|
+
};
|
|
45
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
46
|
+
var useValue = arguments.length > 2;
|
|
47
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
48
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
49
|
+
}
|
|
50
|
+
return useValue ? value : void 0;
|
|
51
|
+
};
|
|
52
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
53
|
+
var ownKeys = function(o) {
|
|
54
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
55
|
+
var ar = [];
|
|
56
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
57
|
+
return ar;
|
|
58
|
+
};
|
|
59
|
+
return ownKeys(o);
|
|
60
|
+
};
|
|
61
|
+
return function (mod) {
|
|
62
|
+
if (mod && mod.__esModule) return mod;
|
|
63
|
+
var result = {};
|
|
64
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
65
|
+
__setModuleDefault(result, mod);
|
|
66
|
+
return result;
|
|
67
|
+
};
|
|
68
|
+
})();
|
|
69
|
+
var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
|
|
70
|
+
if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
|
|
71
|
+
return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
|
|
72
|
+
};
|
|
73
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
74
|
+
exports.WebhookQueueService = void 0;
|
|
75
|
+
const typedi_1 = require("typedi");
|
|
76
|
+
const redis_1 = require("../../db/redis");
|
|
77
|
+
let WebhookQueueService = (() => {
|
|
78
|
+
let _classDecorators = [(0, typedi_1.Service)()];
|
|
79
|
+
let _classDescriptor;
|
|
80
|
+
let _classExtraInitializers = [];
|
|
81
|
+
let _classThis;
|
|
82
|
+
var WebhookQueueService = _classThis = class {
|
|
83
|
+
constructor() {
|
|
84
|
+
this.webhookQueues = new Map(); // BullMQ Queue instances
|
|
85
|
+
}
|
|
86
|
+
generateQueueName(propertyId, pmsType) {
|
|
87
|
+
return `${propertyId}_${pmsType}_webhook`;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Add a webhook to the appropriate queue based on propertyId and pmsType
|
|
91
|
+
* Creates queue if it doesn't exist
|
|
92
|
+
*/
|
|
93
|
+
async addWebhookToQueue(propertyId, pmsType, webhookData, options) {
|
|
94
|
+
const queueName = this.generateQueueName(propertyId, pmsType);
|
|
95
|
+
// Get or create queue using the static method
|
|
96
|
+
const queue = await WebhookQueueService.getOrCreateQueue(queueName, this.webhookQueues);
|
|
97
|
+
// Add job to queue immediately with 5 minute TTL
|
|
98
|
+
const job = await queue.add("webhook-job", {
|
|
99
|
+
propertyId,
|
|
100
|
+
pmsType,
|
|
101
|
+
webhookData,
|
|
102
|
+
timestamp: new Date().toISOString(),
|
|
103
|
+
}, {
|
|
104
|
+
removeOnComplete: { age: 5 * 60 }, // Remove after 5 minutes
|
|
105
|
+
removeOnFail: { age: 5 * 60 }, // Remove failed jobs after 5 minutes
|
|
106
|
+
attempts: 1, // Only try once
|
|
107
|
+
});
|
|
108
|
+
return job.id;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Mark a webhook job as completed (processed successfully)
|
|
112
|
+
* Note: Jobs are now removed immediately when polled, so this method is for logging purposes
|
|
113
|
+
*/
|
|
114
|
+
async markWebhookCompleted(propertyId, pmsType, jobId) {
|
|
115
|
+
// Jobs are removed immediately when polled, so just log completion
|
|
116
|
+
console.log(`Webhook job ${jobId} marked as completed for ${propertyId}_${pmsType}`);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Mark a webhook job as failed
|
|
120
|
+
* Note: Jobs are now removed immediately when polled, so this method is for logging purposes
|
|
121
|
+
*/
|
|
122
|
+
async markWebhookFailed(propertyId, pmsType, jobId, error) {
|
|
123
|
+
// Jobs are removed immediately when polled, so just log failure
|
|
124
|
+
console.error(`Webhook job ${jobId} marked as failed for ${propertyId}_${pmsType}: ${error || "Unknown error"}`);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Poll available webhook from ANY available webhook queue in Redis
|
|
128
|
+
* This method will discover all queues in Redis and filter only webhook queues
|
|
129
|
+
*/
|
|
130
|
+
async pollWebhookFromQueues() {
|
|
131
|
+
try {
|
|
132
|
+
// Get all queue names from Redis (not just local Map)
|
|
133
|
+
const redisClient = (0, redis_1.getRedisClient)();
|
|
134
|
+
const queueKeys = await redisClient.keys("bull:*:id");
|
|
135
|
+
// Filter only webhook queues (PropertyId_pmsType_webhook pattern)
|
|
136
|
+
const webhookQueueKeys = queueKeys
|
|
137
|
+
.map((key) => key.replace("bull:", "").replace(":id", ""))
|
|
138
|
+
.filter((queueName) => {
|
|
139
|
+
const parts = queueName.split("_");
|
|
140
|
+
return parts.length === 3 && parts[2] === "webhook";
|
|
141
|
+
});
|
|
142
|
+
// Check each webhook queue for waiting jobs
|
|
143
|
+
for (const queueName of webhookQueueKeys) {
|
|
144
|
+
try {
|
|
145
|
+
// Create queue instance if not exists locally
|
|
146
|
+
if (!this.webhookQueues.has(queueName)) {
|
|
147
|
+
const { Queue } = await Promise.resolve().then(() => __importStar(require("bullmq")));
|
|
148
|
+
const queue = new Queue(queueName, {
|
|
149
|
+
connection: (0, redis_1.getRedisClient)(),
|
|
150
|
+
});
|
|
151
|
+
this.webhookQueues.set(queueName, queue);
|
|
152
|
+
}
|
|
153
|
+
const queue = this.webhookQueues.get(queueName);
|
|
154
|
+
// Get waiting jobs and take the first one
|
|
155
|
+
const waitingJobs = await queue.getWaiting(0, 1);
|
|
156
|
+
if (waitingJobs.length > 0) {
|
|
157
|
+
const job = waitingJobs[0];
|
|
158
|
+
// Remove the job from the queue to prevent duplicate processing
|
|
159
|
+
await job.remove();
|
|
160
|
+
// Extract propertyId and pmsType from queue name
|
|
161
|
+
const parts = queueName.split("_");
|
|
162
|
+
const propertyId = parts[0];
|
|
163
|
+
const pmsType = parts[1];
|
|
164
|
+
return {
|
|
165
|
+
jobId: job.id,
|
|
166
|
+
data: job.data,
|
|
167
|
+
propertyId,
|
|
168
|
+
pmsType,
|
|
169
|
+
queueName,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
console.error(`Error checking queue ${queueName}:`, error);
|
|
175
|
+
continue; // Try next queue
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return null; // No jobs available in any webhook queue
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
console.error("Error discovering queues from Redis:", error);
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Get all available webhook queue names from Redis
|
|
187
|
+
*/
|
|
188
|
+
async getAllQueueNames() {
|
|
189
|
+
try {
|
|
190
|
+
const redisClient = (0, redis_1.getRedisClient)();
|
|
191
|
+
const queueKeys = await redisClient.keys("bull:*:id");
|
|
192
|
+
// Filter only webhook queues (PropertyId_pmsType_webhook pattern)
|
|
193
|
+
return queueKeys
|
|
194
|
+
.map((key) => key.replace("bull:", "").replace(":id", ""))
|
|
195
|
+
.filter((queueName) => {
|
|
196
|
+
const parts = queueName.split("_");
|
|
197
|
+
return parts.length === 3 && parts[2] === "webhook";
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
console.error("Error getting queue names from Redis:", error);
|
|
202
|
+
return [];
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Get total waiting count across all webhook queues
|
|
207
|
+
*/
|
|
208
|
+
async getTotalWaitingCount() {
|
|
209
|
+
try {
|
|
210
|
+
const redisClient = (0, redis_1.getRedisClient)();
|
|
211
|
+
const queueKeys = await redisClient.keys("bull:*:id");
|
|
212
|
+
let totalCount = 0;
|
|
213
|
+
// Filter only webhook queues and count waiting jobs
|
|
214
|
+
for (const key of queueKeys) {
|
|
215
|
+
const queueName = key.replace("bull:", "").replace(":id", "");
|
|
216
|
+
const parts = queueName.split("_");
|
|
217
|
+
// Only count webhook queues
|
|
218
|
+
if (parts.length === 3 && parts[2] === "webhook") {
|
|
219
|
+
try {
|
|
220
|
+
// Create queue instance if not exists locally
|
|
221
|
+
if (!this.webhookQueues.has(queueName)) {
|
|
222
|
+
const { Queue } = await Promise.resolve().then(() => __importStar(require("bullmq")));
|
|
223
|
+
const queue = new Queue(queueName, {
|
|
224
|
+
connection: (0, redis_1.getRedisClient)(),
|
|
225
|
+
});
|
|
226
|
+
this.webhookQueues.set(queueName, queue);
|
|
227
|
+
}
|
|
228
|
+
const queue = this.webhookQueues.get(queueName);
|
|
229
|
+
const waitingJobs = await queue.getWaiting();
|
|
230
|
+
totalCount += waitingJobs.length;
|
|
231
|
+
}
|
|
232
|
+
catch (error) {
|
|
233
|
+
console.error(`Error getting count for queue ${queueName}:`, error);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return totalCount;
|
|
238
|
+
}
|
|
239
|
+
catch (error) {
|
|
240
|
+
console.error("Error getting total waiting count:", error);
|
|
241
|
+
return 0;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
static async getOrCreateQueue(queueKey, queues) {
|
|
245
|
+
if (queues.has(queueKey)) {
|
|
246
|
+
return queues.get(queueKey);
|
|
247
|
+
}
|
|
248
|
+
const { Queue } = await Promise.resolve().then(() => __importStar(require("bullmq")));
|
|
249
|
+
const queue = new Queue(queueKey, {
|
|
250
|
+
connection: (0, redis_1.getRedisClient)(),
|
|
251
|
+
});
|
|
252
|
+
queues.set(queueKey, queue);
|
|
253
|
+
return queue;
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
__setFunctionName(_classThis, "WebhookQueueService");
|
|
257
|
+
(() => {
|
|
258
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
259
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
260
|
+
WebhookQueueService = _classThis = _classDescriptor.value;
|
|
261
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
262
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
263
|
+
})();
|
|
264
|
+
return WebhookQueueService = _classThis;
|
|
265
|
+
})();
|
|
266
|
+
exports.WebhookQueueService = WebhookQueueService;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./WebhookQueueService";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./WebhookQueueService"), exports);
|