@mulingai-npm/redis 3.13.1 → 3.15.0

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.
@@ -6,6 +6,7 @@ export type MulingstreamListenerData = {
6
6
  token: string;
7
7
  name?: string;
8
8
  firstJoined: number;
9
+ lastHeartbeat: number;
9
10
  language?: string;
10
11
  isActive?: boolean;
11
12
  };
@@ -13,13 +14,14 @@ export declare class MulingstreamListenerManager {
13
14
  private redisClient;
14
15
  constructor(redisClient: RedisClient);
15
16
  private parseHashData;
16
- addListener(listenerData: Omit<MulingstreamListenerData, 'listenerId'>): Promise<string>;
17
+ addListener(listenerData: MulingstreamListenerData): Promise<string>;
17
18
  getAllListeners(): Promise<MulingstreamListenerData[]>;
18
19
  getListenersByRoom(roomId: string): Promise<MulingstreamListenerData[]>;
19
20
  getListener(listenerIdOrToken: string): Promise<MulingstreamListenerData | null>;
20
- removeListenerByToken(token: string): Promise<boolean>;
21
+ removeListener(tokenOrListenerId: string): Promise<MulingstreamListenerData | null>;
21
22
  updateNameLanguage(listenerIdOrToken: string, name: string, language: string): Promise<MulingstreamListenerData | null>;
22
23
  updateSocketId(listenerIdOrToken: string, socketId: string): Promise<MulingstreamListenerData | null>;
23
24
  getTargetSocketIdsByRoomLanguage(roomId: string, language: string): Promise<string[]>;
24
25
  getUniqueLanguagesByRoom(roomId: string): Promise<string[]>;
26
+ updateHeartbeat(listenerIdOrToken: string): Promise<MulingstreamListenerData | null>;
25
27
  }
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MulingstreamListenerManager = void 0;
4
- const uuid_1 = require("uuid");
5
4
  const EXPIRATION = 24 * 60 * 60; // 24 hours in seconds
6
5
  class MulingstreamListenerManager {
7
6
  constructor(redisClient) {
@@ -15,6 +14,7 @@ class MulingstreamListenerManager {
15
14
  token: data.token,
16
15
  name: data.name || '',
17
16
  firstJoined: parseInt(data.firstJoined, 10),
17
+ lastHeartbeat: parseInt(data.lastHeartbeat, 10),
18
18
  language: data.language || '',
19
19
  isActive: data.isActive === 'true'
20
20
  };
@@ -25,7 +25,7 @@ class MulingstreamListenerManager {
25
25
  async addListener(listenerData) {
26
26
  var _a, _b, _c;
27
27
  // You can combine roomId + uuid, or just a uuid, up to you:
28
- const listenerId = `[${listenerData.roomId}]-[${(0, uuid_1.v4)()}]`;
28
+ const listenerId = listenerData.listenerId;
29
29
  // Add listenerId to the set for that room
30
30
  await this.redisClient.sadd(`room:${listenerData.roomId}:listeners`, listenerId);
31
31
  // Store listener data in a hash
@@ -36,6 +36,7 @@ class MulingstreamListenerManager {
36
36
  token: listenerData.token,
37
37
  name: (_b = listenerData.name) !== null && _b !== void 0 ? _b : '',
38
38
  firstJoined: listenerData.firstJoined.toString(),
39
+ lastHeartbeat: listenerData.lastHeartbeat.toString(),
39
40
  language: (_c = listenerData.language) !== null && _c !== void 0 ? _c : '',
40
41
  isActive: 'true'
41
42
  });
@@ -97,17 +98,17 @@ class MulingstreamListenerManager {
97
98
  }
98
99
  return null;
99
100
  }
100
- async removeListenerByToken(token) {
101
- // find the listener by token
102
- const listener = await this.getListener(token);
101
+ async removeListener(tokenOrListenerId) {
102
+ // find the listener by token or listenerId
103
+ const listener = await this.getListener(tokenOrListenerId);
103
104
  if (!listener) {
104
- return false;
105
+ return null;
105
106
  }
106
107
  // remove the listener ID from the room's set
107
108
  await this.redisClient.srem(`room:${listener.roomId}:listeners`, listener.listenerId);
108
109
  // remove the listener data (the hash)
109
110
  await this.redisClient.del(`listener:${listener.listenerId}`);
110
- return true;
111
+ return listener;
111
112
  }
112
113
  async updateNameLanguage(listenerIdOrToken, name, language) {
113
114
  const listener = await this.getListener(listenerIdOrToken);
@@ -161,5 +162,21 @@ class MulingstreamListenerManager {
161
162
  // 4) Map back to just the language strings in order
162
163
  return sortedEntries.map(([language]) => language);
163
164
  }
165
+ async updateHeartbeat(listenerIdOrToken) {
166
+ const listener = await this.getListener(listenerIdOrToken);
167
+ if (!listener) {
168
+ console.warn(`[Heartbeat] Cannot update heartbeat for unknown listener: ${listenerIdOrToken}`);
169
+ return null;
170
+ }
171
+ const now = Date.now();
172
+ // Update the heartbeat timestamp
173
+ await this.redisClient.hset(`listener:${listener.listenerId}`, {
174
+ lastHeartbeat: now.toString()
175
+ });
176
+ // Reset expiration on activity
177
+ await this.redisClient.expire(`listener:${listener.listenerId}`, EXPIRATION);
178
+ console.log(`[Heartbeat] Updated for listener ${listener.listenerId} at ${new Date(now).toISOString()}`);
179
+ return { ...listener, lastHeartbeat: now };
180
+ }
164
181
  }
165
182
  exports.MulingstreamListenerManager = MulingstreamListenerManager;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mulingai-npm/redis",
3
- "version": "3.13.1",
3
+ "version": "3.15.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "repository": {