@mulingai-npm/redis 3.4.0 → 3.4.2
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/README.md +7 -7
- package/dist/enums/redis-database.d.ts +5 -5
- package/dist/enums/redis-database.js +9 -9
- package/dist/loggers/mulingstream-chunk-logger.d.ts +20 -20
- package/dist/loggers/mulingstream-chunk-logger.js +84 -84
- package/dist/managers/mulingstream-chunk-manager.d.ts +112 -111
- package/dist/managers/mulingstream-chunk-manager.js +359 -352
- package/dist/managers/mulingstream-listener-manager.d.ts +29 -29
- package/dist/managers/mulingstream-listener-manager.js +169 -169
- package/dist/managers/mulingstream-speaker-manager.d.ts +37 -37
- package/dist/managers/mulingstream-speaker-manager.js +225 -225
- package/dist/redis-client.d.ts +44 -44
- package/dist/redis-client.js +143 -143
- package/dist/utils/finders.d.ts +1 -1
- package/dist/utils/finders.js +18 -18
- package/package.json +34 -34
|
@@ -1,225 +1,225 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MulingstreamSpeakerManager = void 0;
|
|
4
|
-
const EXPIRATION = 24 * 60 * 60; // 24h
|
|
5
|
-
class MulingstreamSpeakerManager {
|
|
6
|
-
constructor(redisClient) {
|
|
7
|
-
this.redisClient = redisClient;
|
|
8
|
-
}
|
|
9
|
-
parseHash(hash) {
|
|
10
|
-
return {
|
|
11
|
-
speakerId: hash.speakerId,
|
|
12
|
-
userId: hash.userId,
|
|
13
|
-
roomId: hash.roomId,
|
|
14
|
-
socketId: hash.socketId,
|
|
15
|
-
sourceLanguage: hash.sourceLanguage,
|
|
16
|
-
theme: hash.theme,
|
|
17
|
-
prompts: hash.prompts,
|
|
18
|
-
recordingsDuration: parseInt(hash.recordingsDuration, 10) || 0,
|
|
19
|
-
targetLanguages: JSON.parse(hash.targetLanguages || '[]'),
|
|
20
|
-
timestamp: hash.timestamp
|
|
21
|
-
};
|
|
22
|
-
}
|
|
23
|
-
serialize(data) {
|
|
24
|
-
return {
|
|
25
|
-
speakerId: data.speakerId,
|
|
26
|
-
userId: data.userId,
|
|
27
|
-
roomId: data.roomId,
|
|
28
|
-
socketId: data.socketId,
|
|
29
|
-
sourceLanguage: data.sourceLanguage,
|
|
30
|
-
theme: data.theme,
|
|
31
|
-
prompts: data.prompts,
|
|
32
|
-
recordingsDuration: data.recordingsDuration.toString(),
|
|
33
|
-
targetLanguages: JSON.stringify(data.targetLanguages),
|
|
34
|
-
timestamp: data.timestamp
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
buildId(roomId, userId, socketId) {
|
|
38
|
-
return `[${roomId}]-[${userId}]-[${socketId}]`;
|
|
39
|
-
}
|
|
40
|
-
buildKey(speakerId) {
|
|
41
|
-
return `speaker:${speakerId}`;
|
|
42
|
-
}
|
|
43
|
-
async addSpeaker(payload) {
|
|
44
|
-
const speakerId = this.buildId(payload.roomId, payload.userId, payload.socketId);
|
|
45
|
-
const key = this.buildKey(speakerId);
|
|
46
|
-
const speakerData = {
|
|
47
|
-
...payload,
|
|
48
|
-
speakerId,
|
|
49
|
-
timestamp: new Date(Date.now()).toISOString()
|
|
50
|
-
};
|
|
51
|
-
await this.redisClient.hset(key, this.serialize(speakerData));
|
|
52
|
-
await this.redisClient.expire(key, EXPIRATION);
|
|
53
|
-
// index sets / mapping
|
|
54
|
-
await this.redisClient.sadd(`room:${payload.roomId}:speakers`, speakerId);
|
|
55
|
-
await this.redisClient.sadd(`user:${payload.userId}:speakers`, speakerId);
|
|
56
|
-
await this.redisClient.set(`socket:${payload.socketId}:speaker`, speakerId);
|
|
57
|
-
await this.redisClient.expire(`socket:${payload.socketId}:speaker`, EXPIRATION);
|
|
58
|
-
return speakerId;
|
|
59
|
-
}
|
|
60
|
-
async removeSpeakerBySocketId(socketId) {
|
|
61
|
-
const speakerId = await this.redisClient.get(`socket:${socketId}:speaker`);
|
|
62
|
-
if (speakerId === null) {
|
|
63
|
-
return false;
|
|
64
|
-
}
|
|
65
|
-
const removed = await this.removeSpeakerById(speakerId);
|
|
66
|
-
return removed;
|
|
67
|
-
}
|
|
68
|
-
async removeSpeakersByUserId(userId) {
|
|
69
|
-
const ids = await this.redisClient.smembers(`user:${userId}:speakers`);
|
|
70
|
-
if (ids.length === 0) {
|
|
71
|
-
return 0;
|
|
72
|
-
}
|
|
73
|
-
let deletedCount = 0;
|
|
74
|
-
for (const id of ids) {
|
|
75
|
-
if (await this.removeSpeakerById(id)) {
|
|
76
|
-
deletedCount += 1;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
return deletedCount;
|
|
80
|
-
}
|
|
81
|
-
async removeSpeakersByRoomId(roomId) {
|
|
82
|
-
const ids = await this.redisClient.smembers(`room:${roomId}:speakers`);
|
|
83
|
-
if (ids.length === 0) {
|
|
84
|
-
return 0;
|
|
85
|
-
}
|
|
86
|
-
let deletedCount = 0;
|
|
87
|
-
for (const id of ids) {
|
|
88
|
-
if (await this.removeSpeakerById(id)) {
|
|
89
|
-
deletedCount += 1;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
return deletedCount;
|
|
93
|
-
}
|
|
94
|
-
async removeSpeakerById(speakerId) {
|
|
95
|
-
const key = this.buildKey(speakerId);
|
|
96
|
-
const data = await this.redisClient.hgetall(key);
|
|
97
|
-
if (data === null || Object.keys(data).length === 0) {
|
|
98
|
-
// already gone; clean indexes anyway
|
|
99
|
-
await this.cleanIndexes(speakerId);
|
|
100
|
-
return false;
|
|
101
|
-
}
|
|
102
|
-
await this.redisClient.del(key);
|
|
103
|
-
await this.cleanIndexes(speakerId);
|
|
104
|
-
return true;
|
|
105
|
-
}
|
|
106
|
-
async getSpeakerBySpeakerId(speakerId) {
|
|
107
|
-
const key = this.buildKey(speakerId);
|
|
108
|
-
const hash = await this.redisClient.hgetall(key);
|
|
109
|
-
if (hash === null || Object.keys(hash).length === 0) {
|
|
110
|
-
// the hash has expired or was never there – remove any stray index refs
|
|
111
|
-
await this.cleanIndexes(speakerId);
|
|
112
|
-
return null;
|
|
113
|
-
}
|
|
114
|
-
return this.parseHash(hash);
|
|
115
|
-
}
|
|
116
|
-
async getSpeakerBySocketId(socketId) {
|
|
117
|
-
const speakerId = await this.redisClient.get(`socket:${socketId}:speaker`);
|
|
118
|
-
if (speakerId === null) {
|
|
119
|
-
return null;
|
|
120
|
-
}
|
|
121
|
-
const hash = await this.redisClient.hgetall(this.buildKey(speakerId));
|
|
122
|
-
if (hash !== null && Object.keys(hash).length > 0) {
|
|
123
|
-
return this.parseHash(hash);
|
|
124
|
-
}
|
|
125
|
-
// hash expired: tidy indexes
|
|
126
|
-
await this.cleanIndexes(speakerId);
|
|
127
|
-
return null;
|
|
128
|
-
}
|
|
129
|
-
async getSpeakersByRoomId(roomId) {
|
|
130
|
-
const ids = await this.redisClient.smembers(`room:${roomId}:speakers`);
|
|
131
|
-
const result = [];
|
|
132
|
-
for (const id of ids) {
|
|
133
|
-
const hash = await this.redisClient.hgetall(this.buildKey(id));
|
|
134
|
-
if (hash !== null && Object.keys(hash).length > 0) {
|
|
135
|
-
result.push(this.parseHash(hash));
|
|
136
|
-
}
|
|
137
|
-
else {
|
|
138
|
-
await this.cleanIndexes(id);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
return result;
|
|
142
|
-
}
|
|
143
|
-
async getSpeakersByUserId(userId) {
|
|
144
|
-
const ids = await this.redisClient.smembers(`user:${userId}:speakers`);
|
|
145
|
-
const result = [];
|
|
146
|
-
for (const id of ids) {
|
|
147
|
-
const hash = await this.redisClient.hgetall(this.buildKey(id));
|
|
148
|
-
if (hash !== null && Object.keys(hash).length > 0) {
|
|
149
|
-
result.push(this.parseHash(hash));
|
|
150
|
-
}
|
|
151
|
-
else {
|
|
152
|
-
await this.cleanIndexes(id);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
return result;
|
|
156
|
-
}
|
|
157
|
-
async getSpeakerByUserRoom(roomId, userId) {
|
|
158
|
-
const ids = await this.redisClient.smembers(`room:${roomId}:speakers`);
|
|
159
|
-
for (const id of ids) {
|
|
160
|
-
if (id.includes(`]-[${userId}]-[`)) {
|
|
161
|
-
const hash = await this.redisClient.hgetall(this.buildKey(id));
|
|
162
|
-
if (hash !== null && Object.keys(hash).length > 0) {
|
|
163
|
-
return this.parseHash(hash);
|
|
164
|
-
}
|
|
165
|
-
await this.cleanIndexes(id);
|
|
166
|
-
return null;
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
return null;
|
|
170
|
-
}
|
|
171
|
-
async getSpeakersLength(roomId) {
|
|
172
|
-
const speakers = await this.getSpeakersByRoomId(roomId);
|
|
173
|
-
return speakers.length;
|
|
174
|
-
}
|
|
175
|
-
async isRoomEmpty(roomId) {
|
|
176
|
-
const totalSpeakers = await this.getSpeakersLength(roomId);
|
|
177
|
-
return totalSpeakers === 0;
|
|
178
|
-
}
|
|
179
|
-
async updateSourceLanguage(socketId, newLang) {
|
|
180
|
-
const speaker = await this.getSpeakerBySocketId(socketId);
|
|
181
|
-
if (speaker === null) {
|
|
182
|
-
return false;
|
|
183
|
-
}
|
|
184
|
-
await this.redisClient.hset(this.buildKey(speaker.speakerId), {
|
|
185
|
-
sourceLanguage: newLang
|
|
186
|
-
});
|
|
187
|
-
return true;
|
|
188
|
-
}
|
|
189
|
-
async updateTargetLanguages(socketId, languages) {
|
|
190
|
-
const speaker = await this.getSpeakerBySocketId(socketId);
|
|
191
|
-
if (speaker === null) {
|
|
192
|
-
return false;
|
|
193
|
-
}
|
|
194
|
-
await this.redisClient.hset(this.buildKey(speaker.speakerId), {
|
|
195
|
-
targetLanguages: JSON.stringify(languages)
|
|
196
|
-
});
|
|
197
|
-
return true;
|
|
198
|
-
}
|
|
199
|
-
async increaseRecordingDuration(socketId, delta) {
|
|
200
|
-
const speaker = await this.getSpeakerBySocketId(socketId);
|
|
201
|
-
if (speaker === null) {
|
|
202
|
-
return -1;
|
|
203
|
-
}
|
|
204
|
-
speaker.recordingsDuration += delta;
|
|
205
|
-
await this.redisClient.hset(this.buildKey(speaker.speakerId), {
|
|
206
|
-
recordingsDuration: speaker.recordingsDuration.toString()
|
|
207
|
-
});
|
|
208
|
-
return speaker.recordingsDuration;
|
|
209
|
-
}
|
|
210
|
-
async cleanIndexes(speakerId) {
|
|
211
|
-
const parts = speakerId
|
|
212
|
-
.substring(1, speakerId.length - 1) // remove outer [...]
|
|
213
|
-
.split(']-['); // ['roomId','userId','socketId']
|
|
214
|
-
if (parts.length !== 3) {
|
|
215
|
-
return;
|
|
216
|
-
}
|
|
217
|
-
const roomId = parts[0];
|
|
218
|
-
const userId = parts[1];
|
|
219
|
-
const socketId = parts[2];
|
|
220
|
-
await this.redisClient.srem(`room:${roomId}:speakers`, speakerId);
|
|
221
|
-
await this.redisClient.srem(`user:${userId}:speakers`, speakerId);
|
|
222
|
-
await this.redisClient.del(`socket:${socketId}:speaker`);
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
exports.MulingstreamSpeakerManager = MulingstreamSpeakerManager;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MulingstreamSpeakerManager = void 0;
|
|
4
|
+
const EXPIRATION = 24 * 60 * 60; // 24h
|
|
5
|
+
class MulingstreamSpeakerManager {
|
|
6
|
+
constructor(redisClient) {
|
|
7
|
+
this.redisClient = redisClient;
|
|
8
|
+
}
|
|
9
|
+
parseHash(hash) {
|
|
10
|
+
return {
|
|
11
|
+
speakerId: hash.speakerId,
|
|
12
|
+
userId: hash.userId,
|
|
13
|
+
roomId: hash.roomId,
|
|
14
|
+
socketId: hash.socketId,
|
|
15
|
+
sourceLanguage: hash.sourceLanguage,
|
|
16
|
+
theme: hash.theme,
|
|
17
|
+
prompts: hash.prompts,
|
|
18
|
+
recordingsDuration: parseInt(hash.recordingsDuration, 10) || 0,
|
|
19
|
+
targetLanguages: JSON.parse(hash.targetLanguages || '[]'),
|
|
20
|
+
timestamp: hash.timestamp
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
serialize(data) {
|
|
24
|
+
return {
|
|
25
|
+
speakerId: data.speakerId,
|
|
26
|
+
userId: data.userId,
|
|
27
|
+
roomId: data.roomId,
|
|
28
|
+
socketId: data.socketId,
|
|
29
|
+
sourceLanguage: data.sourceLanguage,
|
|
30
|
+
theme: data.theme,
|
|
31
|
+
prompts: data.prompts,
|
|
32
|
+
recordingsDuration: data.recordingsDuration.toString(),
|
|
33
|
+
targetLanguages: JSON.stringify(data.targetLanguages),
|
|
34
|
+
timestamp: data.timestamp
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
buildId(roomId, userId, socketId) {
|
|
38
|
+
return `[${roomId}]-[${userId}]-[${socketId}]`;
|
|
39
|
+
}
|
|
40
|
+
buildKey(speakerId) {
|
|
41
|
+
return `speaker:${speakerId}`;
|
|
42
|
+
}
|
|
43
|
+
async addSpeaker(payload) {
|
|
44
|
+
const speakerId = this.buildId(payload.roomId, payload.userId, payload.socketId);
|
|
45
|
+
const key = this.buildKey(speakerId);
|
|
46
|
+
const speakerData = {
|
|
47
|
+
...payload,
|
|
48
|
+
speakerId,
|
|
49
|
+
timestamp: new Date(Date.now()).toISOString()
|
|
50
|
+
};
|
|
51
|
+
await this.redisClient.hset(key, this.serialize(speakerData));
|
|
52
|
+
await this.redisClient.expire(key, EXPIRATION);
|
|
53
|
+
// index sets / mapping
|
|
54
|
+
await this.redisClient.sadd(`room:${payload.roomId}:speakers`, speakerId);
|
|
55
|
+
await this.redisClient.sadd(`user:${payload.userId}:speakers`, speakerId);
|
|
56
|
+
await this.redisClient.set(`socket:${payload.socketId}:speaker`, speakerId);
|
|
57
|
+
await this.redisClient.expire(`socket:${payload.socketId}:speaker`, EXPIRATION);
|
|
58
|
+
return speakerId;
|
|
59
|
+
}
|
|
60
|
+
async removeSpeakerBySocketId(socketId) {
|
|
61
|
+
const speakerId = await this.redisClient.get(`socket:${socketId}:speaker`);
|
|
62
|
+
if (speakerId === null) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
const removed = await this.removeSpeakerById(speakerId);
|
|
66
|
+
return removed;
|
|
67
|
+
}
|
|
68
|
+
async removeSpeakersByUserId(userId) {
|
|
69
|
+
const ids = await this.redisClient.smembers(`user:${userId}:speakers`);
|
|
70
|
+
if (ids.length === 0) {
|
|
71
|
+
return 0;
|
|
72
|
+
}
|
|
73
|
+
let deletedCount = 0;
|
|
74
|
+
for (const id of ids) {
|
|
75
|
+
if (await this.removeSpeakerById(id)) {
|
|
76
|
+
deletedCount += 1;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return deletedCount;
|
|
80
|
+
}
|
|
81
|
+
async removeSpeakersByRoomId(roomId) {
|
|
82
|
+
const ids = await this.redisClient.smembers(`room:${roomId}:speakers`);
|
|
83
|
+
if (ids.length === 0) {
|
|
84
|
+
return 0;
|
|
85
|
+
}
|
|
86
|
+
let deletedCount = 0;
|
|
87
|
+
for (const id of ids) {
|
|
88
|
+
if (await this.removeSpeakerById(id)) {
|
|
89
|
+
deletedCount += 1;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return deletedCount;
|
|
93
|
+
}
|
|
94
|
+
async removeSpeakerById(speakerId) {
|
|
95
|
+
const key = this.buildKey(speakerId);
|
|
96
|
+
const data = await this.redisClient.hgetall(key);
|
|
97
|
+
if (data === null || Object.keys(data).length === 0) {
|
|
98
|
+
// already gone; clean indexes anyway
|
|
99
|
+
await this.cleanIndexes(speakerId);
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
await this.redisClient.del(key);
|
|
103
|
+
await this.cleanIndexes(speakerId);
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
async getSpeakerBySpeakerId(speakerId) {
|
|
107
|
+
const key = this.buildKey(speakerId);
|
|
108
|
+
const hash = await this.redisClient.hgetall(key);
|
|
109
|
+
if (hash === null || Object.keys(hash).length === 0) {
|
|
110
|
+
// the hash has expired or was never there – remove any stray index refs
|
|
111
|
+
await this.cleanIndexes(speakerId);
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
return this.parseHash(hash);
|
|
115
|
+
}
|
|
116
|
+
async getSpeakerBySocketId(socketId) {
|
|
117
|
+
const speakerId = await this.redisClient.get(`socket:${socketId}:speaker`);
|
|
118
|
+
if (speakerId === null) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
const hash = await this.redisClient.hgetall(this.buildKey(speakerId));
|
|
122
|
+
if (hash !== null && Object.keys(hash).length > 0) {
|
|
123
|
+
return this.parseHash(hash);
|
|
124
|
+
}
|
|
125
|
+
// hash expired: tidy indexes
|
|
126
|
+
await this.cleanIndexes(speakerId);
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
async getSpeakersByRoomId(roomId) {
|
|
130
|
+
const ids = await this.redisClient.smembers(`room:${roomId}:speakers`);
|
|
131
|
+
const result = [];
|
|
132
|
+
for (const id of ids) {
|
|
133
|
+
const hash = await this.redisClient.hgetall(this.buildKey(id));
|
|
134
|
+
if (hash !== null && Object.keys(hash).length > 0) {
|
|
135
|
+
result.push(this.parseHash(hash));
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
await this.cleanIndexes(id);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return result;
|
|
142
|
+
}
|
|
143
|
+
async getSpeakersByUserId(userId) {
|
|
144
|
+
const ids = await this.redisClient.smembers(`user:${userId}:speakers`);
|
|
145
|
+
const result = [];
|
|
146
|
+
for (const id of ids) {
|
|
147
|
+
const hash = await this.redisClient.hgetall(this.buildKey(id));
|
|
148
|
+
if (hash !== null && Object.keys(hash).length > 0) {
|
|
149
|
+
result.push(this.parseHash(hash));
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
await this.cleanIndexes(id);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return result;
|
|
156
|
+
}
|
|
157
|
+
async getSpeakerByUserRoom(roomId, userId) {
|
|
158
|
+
const ids = await this.redisClient.smembers(`room:${roomId}:speakers`);
|
|
159
|
+
for (const id of ids) {
|
|
160
|
+
if (id.includes(`]-[${userId}]-[`)) {
|
|
161
|
+
const hash = await this.redisClient.hgetall(this.buildKey(id));
|
|
162
|
+
if (hash !== null && Object.keys(hash).length > 0) {
|
|
163
|
+
return this.parseHash(hash);
|
|
164
|
+
}
|
|
165
|
+
await this.cleanIndexes(id);
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
async getSpeakersLength(roomId) {
|
|
172
|
+
const speakers = await this.getSpeakersByRoomId(roomId);
|
|
173
|
+
return speakers.length;
|
|
174
|
+
}
|
|
175
|
+
async isRoomEmpty(roomId) {
|
|
176
|
+
const totalSpeakers = await this.getSpeakersLength(roomId);
|
|
177
|
+
return totalSpeakers === 0;
|
|
178
|
+
}
|
|
179
|
+
async updateSourceLanguage(socketId, newLang) {
|
|
180
|
+
const speaker = await this.getSpeakerBySocketId(socketId);
|
|
181
|
+
if (speaker === null) {
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
await this.redisClient.hset(this.buildKey(speaker.speakerId), {
|
|
185
|
+
sourceLanguage: newLang
|
|
186
|
+
});
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
async updateTargetLanguages(socketId, languages) {
|
|
190
|
+
const speaker = await this.getSpeakerBySocketId(socketId);
|
|
191
|
+
if (speaker === null) {
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
await this.redisClient.hset(this.buildKey(speaker.speakerId), {
|
|
195
|
+
targetLanguages: JSON.stringify(languages)
|
|
196
|
+
});
|
|
197
|
+
return true;
|
|
198
|
+
}
|
|
199
|
+
async increaseRecordingDuration(socketId, delta) {
|
|
200
|
+
const speaker = await this.getSpeakerBySocketId(socketId);
|
|
201
|
+
if (speaker === null) {
|
|
202
|
+
return -1;
|
|
203
|
+
}
|
|
204
|
+
speaker.recordingsDuration += delta;
|
|
205
|
+
await this.redisClient.hset(this.buildKey(speaker.speakerId), {
|
|
206
|
+
recordingsDuration: speaker.recordingsDuration.toString()
|
|
207
|
+
});
|
|
208
|
+
return speaker.recordingsDuration;
|
|
209
|
+
}
|
|
210
|
+
async cleanIndexes(speakerId) {
|
|
211
|
+
const parts = speakerId
|
|
212
|
+
.substring(1, speakerId.length - 1) // remove outer [...]
|
|
213
|
+
.split(']-['); // ['roomId','userId','socketId']
|
|
214
|
+
if (parts.length !== 3) {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
const roomId = parts[0];
|
|
218
|
+
const userId = parts[1];
|
|
219
|
+
const socketId = parts[2];
|
|
220
|
+
await this.redisClient.srem(`room:${roomId}:speakers`, speakerId);
|
|
221
|
+
await this.redisClient.srem(`user:${userId}:speakers`, speakerId);
|
|
222
|
+
await this.redisClient.del(`socket:${socketId}:speaker`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
exports.MulingstreamSpeakerManager = MulingstreamSpeakerManager;
|
package/dist/redis-client.d.ts
CHANGED
|
@@ -1,44 +1,44 @@
|
|
|
1
|
-
import IORedis from 'ioredis';
|
|
2
|
-
export interface RedisConfig {
|
|
3
|
-
host: string;
|
|
4
|
-
port: number;
|
|
5
|
-
password?: string;
|
|
6
|
-
db: number;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Thin wrapper around ioredis that exposes exactly the helpers used by the two
|
|
10
|
-
* managers. All helpers are 1‑to‑1 pass‑through so there is no behavioural
|
|
11
|
-
* change – this merely centralises typing and keeps the rest of the codebase
|
|
12
|
-
* clean.
|
|
13
|
-
*/
|
|
14
|
-
export declare class RedisClient {
|
|
15
|
-
private client;
|
|
16
|
-
constructor(config: RedisConfig);
|
|
17
|
-
set(key: string, value: string): Promise<void>;
|
|
18
|
-
get(key: string): Promise<string | null>;
|
|
19
|
-
del(key: string): Promise<number>;
|
|
20
|
-
exists(key: string): Promise<number>;
|
|
21
|
-
expire(key: string, seconds: number): Promise<number>;
|
|
22
|
-
sadd(key: string, ...values: string[]): Promise<number>;
|
|
23
|
-
srem(key: string, ...values: string[]): Promise<number>;
|
|
24
|
-
smembers(key: string): Promise<string[]>;
|
|
25
|
-
hset(key: string, data: Record<string, string>): Promise<number>;
|
|
26
|
-
hgetall(key: string): Promise<Record<string, string>>;
|
|
27
|
-
zadd(key: string, score: number, member: string): Promise<number>;
|
|
28
|
-
zrange(key: string, start: number, stop: number): Promise<string[]>;
|
|
29
|
-
zremrangebyrank(key: string, start: number, stop: number): Promise<number>;
|
|
30
|
-
zrangebyscore(key: string, min: number | string, max: number | string): Promise<string[]>;
|
|
31
|
-
zrem(key: string, ...members: string[]): Promise<number>;
|
|
32
|
-
scan(cursor: number, pattern: string, count?: number): Promise<[string, string[]]>;
|
|
33
|
-
keys(pattern: string): Promise<string[]>;
|
|
34
|
-
pipeline(): ReturnType<IORedis['pipeline']>;
|
|
35
|
-
unlink(...keys: string[]): Promise<number>;
|
|
36
|
-
jsonSet<T>(key: string, path: string, value: T): Promise<string>;
|
|
37
|
-
jsonGet<T>(key: string, path: string): Promise<T | null>;
|
|
38
|
-
jsonDel(key: string, path: string): Promise<number>;
|
|
39
|
-
jsonArrAppend<T>(key: string, path: string, ...values: T[]): Promise<number>;
|
|
40
|
-
jsonArrLen(key: string, path: string): Promise<number | null>;
|
|
41
|
-
jsonArrPop(key: string, path: string, index?: number): Promise<any>;
|
|
42
|
-
flushAll(): Promise<string>;
|
|
43
|
-
flushDb(): Promise<string>;
|
|
44
|
-
}
|
|
1
|
+
import IORedis from 'ioredis';
|
|
2
|
+
export interface RedisConfig {
|
|
3
|
+
host: string;
|
|
4
|
+
port: number;
|
|
5
|
+
password?: string;
|
|
6
|
+
db: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Thin wrapper around ioredis that exposes exactly the helpers used by the two
|
|
10
|
+
* managers. All helpers are 1‑to‑1 pass‑through so there is no behavioural
|
|
11
|
+
* change – this merely centralises typing and keeps the rest of the codebase
|
|
12
|
+
* clean.
|
|
13
|
+
*/
|
|
14
|
+
export declare class RedisClient {
|
|
15
|
+
private client;
|
|
16
|
+
constructor(config: RedisConfig);
|
|
17
|
+
set(key: string, value: string): Promise<void>;
|
|
18
|
+
get(key: string): Promise<string | null>;
|
|
19
|
+
del(key: string): Promise<number>;
|
|
20
|
+
exists(key: string): Promise<number>;
|
|
21
|
+
expire(key: string, seconds: number): Promise<number>;
|
|
22
|
+
sadd(key: string, ...values: string[]): Promise<number>;
|
|
23
|
+
srem(key: string, ...values: string[]): Promise<number>;
|
|
24
|
+
smembers(key: string): Promise<string[]>;
|
|
25
|
+
hset(key: string, data: Record<string, string>): Promise<number>;
|
|
26
|
+
hgetall(key: string): Promise<Record<string, string>>;
|
|
27
|
+
zadd(key: string, score: number, member: string): Promise<number>;
|
|
28
|
+
zrange(key: string, start: number, stop: number): Promise<string[]>;
|
|
29
|
+
zremrangebyrank(key: string, start: number, stop: number): Promise<number>;
|
|
30
|
+
zrangebyscore(key: string, min: number | string, max: number | string): Promise<string[]>;
|
|
31
|
+
zrem(key: string, ...members: string[]): Promise<number>;
|
|
32
|
+
scan(cursor: number, pattern: string, count?: number): Promise<[string, string[]]>;
|
|
33
|
+
keys(pattern: string): Promise<string[]>;
|
|
34
|
+
pipeline(): ReturnType<IORedis['pipeline']>;
|
|
35
|
+
unlink(...keys: string[]): Promise<number>;
|
|
36
|
+
jsonSet<T>(key: string, path: string, value: T): Promise<string>;
|
|
37
|
+
jsonGet<T>(key: string, path: string): Promise<T | null>;
|
|
38
|
+
jsonDel(key: string, path: string): Promise<number>;
|
|
39
|
+
jsonArrAppend<T>(key: string, path: string, ...values: T[]): Promise<number>;
|
|
40
|
+
jsonArrLen(key: string, path: string): Promise<number | null>;
|
|
41
|
+
jsonArrPop(key: string, path: string, index?: number): Promise<any>;
|
|
42
|
+
flushAll(): Promise<string>;
|
|
43
|
+
flushDb(): Promise<string>;
|
|
44
|
+
}
|