@aichatwar/shared 1.0.153 → 1.0.155

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.
@@ -22,11 +22,13 @@ class Publisher {
22
22
  if (!this.producer)
23
23
  throw new Error('Producer not defined');
24
24
  let lastError = null;
25
+ const key = data.id || data.messageId || data.roomId || undefined;
25
26
  for (let attempt = 1; attempt <= this.maxRetries; attempt++) {
26
27
  try {
27
28
  const result = yield this.producer.send({
28
29
  topic: this.topic,
29
30
  messages: [{
31
+ key: key || null,
30
32
  value: JSON.stringify(data),
31
33
  timestamp: Date.now().toString()
32
34
  }],
@@ -0,0 +1,9 @@
1
+ import { Producer } from 'kafkajs';
2
+ export interface RetryWithDlqOptions {
3
+ maxRetries?: number;
4
+ baseDelayMs?: number;
5
+ dlqTopic: string;
6
+ producer: Producer;
7
+ context?: string;
8
+ }
9
+ export declare function retryWithDlq<T>(fn: () => Promise<T>, originalData: unknown, options: RetryWithDlqOptions): Promise<T | null>;
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.retryWithDlq = retryWithDlq;
13
+ function retryWithDlq(fn, originalData, options) {
14
+ return __awaiter(this, void 0, void 0, function* () {
15
+ const { maxRetries = 3, baseDelayMs = 1000, dlqTopic, producer, context = '' } = options;
16
+ let lastError;
17
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
18
+ try {
19
+ return yield fn();
20
+ }
21
+ catch (err) {
22
+ lastError = err;
23
+ const retriable = err.retryable !== false;
24
+ if (!retriable || attempt === maxRetries) {
25
+ break;
26
+ }
27
+ const delay = baseDelayMs * Math.pow(2, attempt - 1);
28
+ console.warn(`[${context}] Attempt ${attempt}/${maxRetries} failed (retrying in ${delay}ms):`, err.message || err);
29
+ yield new Promise((r) => setTimeout(r, delay));
30
+ }
31
+ }
32
+ console.error(`[${context}] All ${maxRetries} attempts failed, sending to DLQ: ${dlqTopic}`, (lastError === null || lastError === void 0 ? void 0 : lastError.message) || lastError);
33
+ try {
34
+ yield producer.send({
35
+ topic: dlqTopic,
36
+ messages: [
37
+ {
38
+ key: (originalData === null || originalData === void 0 ? void 0 : originalData.id) || (originalData === null || originalData === void 0 ? void 0 : originalData.messageId) || null,
39
+ value: JSON.stringify({
40
+ originalData,
41
+ error: (lastError === null || lastError === void 0 ? void 0 : lastError.message) || 'Unknown error',
42
+ failedAt: new Date().toISOString(),
43
+ attempts: maxRetries,
44
+ context,
45
+ }),
46
+ timestamp: Date.now().toString(),
47
+ },
48
+ ],
49
+ });
50
+ }
51
+ catch (dlqErr) {
52
+ console.error(`[${context}] CRITICAL: Failed to publish to DLQ ${dlqTopic}:`, dlqErr.message);
53
+ }
54
+ return null;
55
+ });
56
+ }
@@ -83,6 +83,12 @@ export declare enum Subjects {
83
83
  AgentDraftCommentCreated = "agent.draft.comment.created",
84
84
  AgentDraftReactionCreated = "agent.draft.reaction.created",
85
85
  AgentDraftConnectionRequestCreated = "agent.draft.connection.request.created",
86
+ AiMessageCreatedDlq = "ai.message.created.dlq",
87
+ MessageCreatedDlq = "message.created.dlq",
88
+ FriendshipRequestedDlq = "friendship.requested.dlq",
89
+ NotificationCreatedDlq = "notification.created.dlq",
90
+ AgentIngestedDlq = "agent.ingested.dlq",
91
+ ARMessageRequestDlq = "agent-chat.message.request.dlq",
86
92
  AgentChatMessageRequest = "agent-chat.message.request",
87
93
  AgentChatStreamStart = "agent-chat.stream.start",
88
94
  AgentChatStreamChunk = "agent-chat.stream.chunk",
@@ -90,6 +90,13 @@ var Subjects;
90
90
  Subjects["AgentDraftCommentCreated"] = "agent.draft.comment.created";
91
91
  Subjects["AgentDraftReactionCreated"] = "agent.draft.reaction.created";
92
92
  Subjects["AgentDraftConnectionRequestCreated"] = "agent.draft.connection.request.created";
93
+ // Dead Letter Queues
94
+ Subjects["AiMessageCreatedDlq"] = "ai.message.created.dlq";
95
+ Subjects["MessageCreatedDlq"] = "message.created.dlq";
96
+ Subjects["FriendshipRequestedDlq"] = "friendship.requested.dlq";
97
+ Subjects["NotificationCreatedDlq"] = "notification.created.dlq";
98
+ Subjects["AgentIngestedDlq"] = "agent.ingested.dlq";
99
+ Subjects["ARMessageRequestDlq"] = "agent-chat.message.request.dlq";
93
100
  // Agent Chat Events (renamed from AR chat)
94
101
  Subjects["AgentChatMessageRequest"] = "agent-chat.message.request";
95
102
  Subjects["AgentChatStreamStart"] = "agent-chat.stream.start";
package/build/index.d.ts CHANGED
@@ -18,6 +18,7 @@ export * from "./events/nats/baseListener";
18
18
  export * from "./events/nats/basePublisher";
19
19
  export * from "./events/kafka/baseListener";
20
20
  export * from "./events/kafka/basePublisher";
21
+ export * from "./events/kafka/dlq";
21
22
  export type { EachMessagePayload } from "./events/kafka/baseListener";
22
23
  export * from "./events/subjects";
23
24
  export * from "./events/profileEvents";
package/build/index.js CHANGED
@@ -35,6 +35,7 @@ __exportStar(require("./events/nats/baseListener"), exports);
35
35
  __exportStar(require("./events/nats/basePublisher"), exports);
36
36
  __exportStar(require("./events/kafka/baseListener"), exports);
37
37
  __exportStar(require("./events/kafka/basePublisher"), exports);
38
+ __exportStar(require("./events/kafka/dlq"), exports);
38
39
  __exportStar(require("./events/subjects"), exports);
39
40
  __exportStar(require("./events/profileEvents"), exports);
40
41
  __exportStar(require("./events/friendshipEvents"), exports);
@@ -26,7 +26,7 @@ const extractJWTPayload = (req, res, next) => {
26
26
  }
27
27
  // Verify and extract JWT payload
28
28
  try {
29
- const payload = jsonwebtoken_1.default.verify(token, process.env.JWT_DEV);
29
+ const payload = jsonwebtoken_1.default.verify(token, process.env.JWT_DEV, { algorithms: ['HS256'] });
30
30
  req.jwtPayload = payload;
31
31
  }
32
32
  catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aichatwar/shared",
3
- "version": "1.0.153",
3
+ "version": "1.0.155",
4
4
  "main": "./build/index.js",
5
5
  "typs": "./build/index.d.ts",
6
6
  "files": [