@mulingai-npm/redis 3.14.0 → 3.16.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,8 +6,8 @@ export type MulingstreamListenerData = {
6
6
  token: string;
7
7
  name?: string;
8
8
  firstJoined: number;
9
+ lastHeartbeat: number;
9
10
  language?: string;
10
- isActive?: boolean;
11
11
  };
12
12
  export declare class MulingstreamListenerManager {
13
13
  private redisClient;
@@ -17,9 +17,10 @@ export declare class MulingstreamListenerManager {
17
17
  getAllListeners(): Promise<MulingstreamListenerData[]>;
18
18
  getListenersByRoom(roomId: string): Promise<MulingstreamListenerData[]>;
19
19
  getListener(listenerIdOrToken: string): Promise<MulingstreamListenerData | null>;
20
- removeListenerByToken(token: string): Promise<boolean>;
20
+ removeListener(tokenOrListenerId: string): Promise<MulingstreamListenerData | null>;
21
21
  updateNameLanguage(listenerIdOrToken: string, name: string, language: string): Promise<MulingstreamListenerData | null>;
22
22
  updateSocketId(listenerIdOrToken: string, socketId: string): Promise<MulingstreamListenerData | null>;
23
23
  getTargetSocketIdsByRoomLanguage(roomId: string, language: string): Promise<string[]>;
24
24
  getUniqueLanguagesByRoom(roomId: string): Promise<string[]>;
25
+ updateHeartbeat(listenerIdOrToken: string): Promise<MulingstreamListenerData | null>;
25
26
  }
@@ -14,8 +14,8 @@ class MulingstreamListenerManager {
14
14
  token: data.token,
15
15
  name: data.name || '',
16
16
  firstJoined: parseInt(data.firstJoined, 10),
17
- language: data.language || '',
18
- isActive: data.isActive === 'true'
17
+ lastHeartbeat: parseInt(data.lastHeartbeat, 10),
18
+ language: data.language || ''
19
19
  };
20
20
  }
21
21
  // Creates a new listener.
@@ -35,8 +35,8 @@ class MulingstreamListenerManager {
35
35
  token: listenerData.token,
36
36
  name: (_b = listenerData.name) !== null && _b !== void 0 ? _b : '',
37
37
  firstJoined: listenerData.firstJoined.toString(),
38
- language: (_c = listenerData.language) !== null && _c !== void 0 ? _c : '',
39
- isActive: 'true'
38
+ lastHeartbeat: listenerData.lastHeartbeat.toString(),
39
+ language: (_c = listenerData.language) !== null && _c !== void 0 ? _c : ''
40
40
  });
41
41
  // expire listener
42
42
  await this.redisClient.expire(`listener:${listenerId}`, EXPIRATION);
@@ -96,17 +96,17 @@ class MulingstreamListenerManager {
96
96
  }
97
97
  return null;
98
98
  }
99
- async removeListenerByToken(token) {
100
- // find the listener by token
101
- const listener = await this.getListener(token);
99
+ async removeListener(tokenOrListenerId) {
100
+ // find the listener by token or listenerId
101
+ const listener = await this.getListener(tokenOrListenerId);
102
102
  if (!listener) {
103
- return false;
103
+ return null;
104
104
  }
105
105
  // remove the listener ID from the room's set
106
106
  await this.redisClient.srem(`room:${listener.roomId}:listeners`, listener.listenerId);
107
107
  // remove the listener data (the hash)
108
108
  await this.redisClient.del(`listener:${listener.listenerId}`);
109
- return true;
109
+ return listener;
110
110
  }
111
111
  async updateNameLanguage(listenerIdOrToken, name, language) {
112
112
  const listener = await this.getListener(listenerIdOrToken);
@@ -134,7 +134,8 @@ class MulingstreamListenerManager {
134
134
  async getTargetSocketIdsByRoomLanguage(roomId, language) {
135
135
  const listeners = await this.getListenersByRoom(roomId);
136
136
  const filteredListeners = listeners.filter((listener) => {
137
- return listener.isActive === true && listener.language === language && listener.socketId && listener.socketId.trim() !== '';
137
+ // Only check language - socketId always exists
138
+ return listener.language === language;
138
139
  });
139
140
  return filteredListeners.map((listener) => listener.socketId);
140
141
  }
@@ -160,5 +161,21 @@ class MulingstreamListenerManager {
160
161
  // 4) Map back to just the language strings in order
161
162
  return sortedEntries.map(([language]) => language);
162
163
  }
164
+ async updateHeartbeat(listenerIdOrToken) {
165
+ const listener = await this.getListener(listenerIdOrToken);
166
+ if (!listener) {
167
+ console.warn(`[Heartbeat] Cannot update heartbeat for unknown listener: ${listenerIdOrToken}`);
168
+ return null;
169
+ }
170
+ const now = Date.now();
171
+ // Update the heartbeat timestamp
172
+ await this.redisClient.hset(`listener:${listener.listenerId}`, {
173
+ lastHeartbeat: now.toString()
174
+ });
175
+ // Reset expiration on activity
176
+ await this.redisClient.expire(`listener:${listener.listenerId}`, EXPIRATION);
177
+ console.log(`[Heartbeat] Updated for listener ${listener.listenerId} at ${new Date(now).toISOString()}`);
178
+ return { ...listener, lastHeartbeat: now };
179
+ }
163
180
  }
164
181
  exports.MulingstreamListenerManager = MulingstreamListenerManager;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mulingai-npm/redis",
3
- "version": "3.14.0",
3
+ "version": "3.16.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "repository": {