@mulingai-npm/redis 1.14.1 → 2.0.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.
@@ -1,18 +1,13 @@
1
1
  import { RedisClient } from '../redis-client';
2
2
  export type StepStatus = 'INIT' | 'DISCARDED' | 'READY' | 'USED';
3
- export type MulingstreamChunkStatus = 'INIT' | 'STARTED' | 'FINISHED' | 'CANCELED' | 'USED';
4
- export type MulingstreamChunkStep = 'RECEIVED' | 'STT' | 'TRANSLATION' | 'TTS' | 'EMITTED';
5
3
  export type SttProvider = 'azure' | 'whisper' | 'google' | 'aws';
6
4
  export type MulingstreamChunkData = {
7
- mulingstreamChunkId: string;
8
- roomId: string;
9
5
  chunkNumber: number;
10
6
  language: string;
11
7
  sttProviders: SttProvider[];
12
8
  targetLanguages: string[];
13
9
  finalTranscription: string;
14
- mulingstreamChunkStatus: MulingstreamChunkStatus;
15
- mulingstreamChunkStep: MulingstreamChunkStep;
10
+ sttStatus: StepStatus;
16
11
  audioChunk: {
17
12
  start: number;
18
13
  end: number;
@@ -45,7 +40,31 @@ export type MulingstreamChunkData = {
45
40
  export declare class MulingstreamChunkManager {
46
41
  private redisClient;
47
42
  constructor(redisClient: RedisClient);
48
- private parseHashData;
43
+ /**
44
+ * Initializes a room in Redis as an empty JSON array.
45
+ * If the key [roomId] already exists, we do NOT overwrite it.
46
+ * Returns true if room was created, false if room already existed.
47
+ */
48
+ initRoom(roomId: string): Promise<boolean>;
49
+ /**
50
+ * Returns all rooms. This is naive if you store many other keys in Redis,
51
+ * because we search keys for pattern "[*]".
52
+ * Adjust as needed if you have a separate naming prefix.
53
+ */
54
+ getRooms(): Promise<string[]>;
55
+ /**
56
+ * Returns the entire array of chunks for the given roomId,
57
+ * or null if the room doesn't exist in Redis.
58
+ */
59
+ getMulingstreamChunksByRoom(roomId: string): Promise<MulingstreamChunkData[] | null>;
60
+ /**
61
+ * Returns the room array "as is" for debugging
62
+ * (same as getMulingstreamChunksByRoom in this example).
63
+ */
64
+ getRoomById(roomId: string): Promise<MulingstreamChunkData[] | null>;
65
+ /**
66
+ * Adds a new Mulingstream chunk to the array stored at [${roomId}].
67
+ */
49
68
  addMulingstreamChunk(params: {
50
69
  roomId: string;
51
70
  chunkNumber: number;
@@ -58,28 +77,31 @@ export declare class MulingstreamChunkManager {
58
77
  theme: string;
59
78
  sttProviders: SttProvider[];
60
79
  targetLanguages: string[];
61
- }): Promise<string>;
62
- getMulingstreamChunks(): Promise<MulingstreamChunkData[]>;
63
- getMulingstreamChunk(mulingstreamChunkId: string): Promise<MulingstreamChunkData | null>;
64
- getMulingstreamChunksByRoom(roomId: string): Promise<MulingstreamChunkData[]>;
65
- getByChunkNumber(chunkNumber: number, roomId: string): Promise<MulingstreamChunkData | null>;
66
- updateMulingstreamChunkStatus(mulingstreamChunkId: string, mulingstreamChunkStep: MulingstreamChunkStep, mulingstreamChunkStatus: MulingstreamChunkStatus): Promise<boolean>;
67
- updateFinalTranscription(mulingstreamChunkId: string, finalTranscription: string): Promise<boolean>;
68
- updateSttStatus(mulingstreamChunkId: string, service: SttProvider, status: StepStatus): Promise<boolean>;
69
- updateTranscription(mulingstreamChunkId: string, service: SttProvider, transcription: string, sttStatus: StepStatus): Promise<boolean>;
70
- /****
71
- * Discards all post-STT steps for a given chunk, i.e. sets
72
- * all translation[].status and all tts[].status to "DISCARDED".
73
- ****/
74
- discardAllPostStt(mulingstreamChunkId: string): Promise<boolean>;
75
- /****
76
- * Discards all post-translation steps for a given chunk, i.e. sets
77
- * all tts[].status to "DISCARDED" (leaves translation alone).
78
- ****/
79
- discardAllPostTranslation(mulingstreamChunkId: string): Promise<boolean>;
80
- /****
81
- * Discards a specific language in both the translation and tts objects,
82
- * setting status to DISCARDED for just that one language.
83
- ****/
84
- discardLanguage(mulingstreamChunkId: string, language: string): Promise<boolean>;
80
+ }): Promise<void>;
81
+ /**
82
+ * Given roomId and chunkNumber, return the single chunk from the array
83
+ * or null if not found.
84
+ */
85
+ getMulingstreamChunkById(roomId: string, chunkNumber: number): Promise<MulingstreamChunkData | null>;
86
+ /**
87
+ * Update STT fields for a given chunk.
88
+ * If transcription or sttStatus is null, skip that field.
89
+ */
90
+ updateStt(roomId: string, chunkNumber: number, sttProvider: SttProvider, options: {
91
+ transcription?: string;
92
+ sttStatus?: StepStatus;
93
+ }): Promise<boolean>;
94
+ /**
95
+ * Update the final transcription field for a chunk.
96
+ */
97
+ updateFinalTranscription(roomId: string, chunkNumber: number, transcription: string, sttStatus: StepStatus): Promise<boolean>;
98
+ /**
99
+ * Discards all post-STT steps for a given chunk:
100
+ * sets all translation[].status & tts[].status to "DISCARDED".
101
+ */
102
+ discardPostStt(roomId: string, chunkNumber: number): Promise<boolean>;
103
+ /**
104
+ * Discards a specific language in both translation and tts for a chunk.
105
+ */
106
+ discardLanguage(roomId: string, chunkNumber: number, language: string): Promise<boolean>;
85
107
  }
@@ -1,44 +1,64 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MulingstreamChunkManager = void 0;
4
- const uuid_1 = require("uuid");
5
4
  const EXPIRATION = 12 * 60 * 60; // 12 hours in seconds
6
5
  class MulingstreamChunkManager {
7
6
  constructor(redisClient) {
8
7
  this.redisClient = redisClient;
9
8
  }
10
- parseHashData(data) {
11
- // Parse the arrays and nested JSON fields
12
- const sttProviders = JSON.parse(data.sttProviders);
13
- const targetLanguages = JSON.parse(data.targetLanguages);
14
- const audioChunk = JSON.parse(data.audioChunk);
15
- const stt = JSON.parse(data.stt);
16
- const translation = JSON.parse(data.translation);
17
- const tts = JSON.parse(data.tts);
18
- return {
19
- mulingstreamChunkId: data.mulingstreamChunkId,
20
- roomId: data.roomId,
21
- chunkNumber: parseInt(data.chunkNumber, 10),
22
- language: data.language,
23
- sttProviders,
24
- targetLanguages,
25
- finalTranscription: data.finalTranscription,
26
- mulingstreamChunkStatus: data.mulingstreamChunkStatus,
27
- mulingstreamChunkStep: data.mulingstreamChunkStep,
28
- audioChunk,
29
- stt,
30
- translation,
31
- tts
32
- };
9
+ /**
10
+ * Initializes a room in Redis as an empty JSON array.
11
+ * If the key [roomId] already exists, we do NOT overwrite it.
12
+ * Returns true if room was created, false if room already existed.
13
+ */
14
+ async initRoom(roomId) {
15
+ // Check if the key already exists (JSON.GET)
16
+ const existing = await this.redisClient.jsonGet(`[${roomId}]`, '.');
17
+ if (existing !== null) {
18
+ // Already exists
19
+ return false;
20
+ }
21
+ // Create an empty array at the root
22
+ await this.redisClient.jsonSet(`[${roomId}]`, '.', []);
23
+ await this.redisClient.expire(`[${roomId}]`, EXPIRATION);
24
+ return true;
25
+ }
26
+ /**
27
+ * Returns all rooms. This is naive if you store many other keys in Redis,
28
+ * because we search keys for pattern "[*]".
29
+ * Adjust as needed if you have a separate naming prefix.
30
+ */
31
+ async getRooms() {
32
+ // e.g., if we store everything as [foo], [bar], etc., we do:
33
+ const rooms = await this.redisClient.keys('\\[*\\]');
34
+ // This returns the raw keys, e.g. ['[myRoom]', '[anotherRoom]']
35
+ // We might want to strip off the brackets:
36
+ return rooms.map((k) => k.replace(/^\[|\]$/g, ''));
37
+ }
38
+ /**
39
+ * Returns the entire array of chunks for the given roomId,
40
+ * or null if the room doesn't exist in Redis.
41
+ */
42
+ async getMulingstreamChunksByRoom(roomId) {
43
+ // JSON.GET [roomId] .
44
+ const chunks = await this.redisClient.jsonGet(`[${roomId}]`, '.');
45
+ if (chunks === null)
46
+ return null; // room not found
47
+ return chunks;
48
+ }
49
+ /**
50
+ * Returns the room array "as is" for debugging
51
+ * (same as getMulingstreamChunksByRoom in this example).
52
+ */
53
+ async getRoomById(roomId) {
54
+ return this.getMulingstreamChunksByRoom(roomId);
33
55
  }
34
- // Adds a new mulingstream chunk.
35
- // - Creates a unique mulingstreamChunkId.
36
- // - Stores the chunk data in a Redis hash under `mulingstreamChunk:{mulingstreamChunkId}`.
37
- // - Applies an expiration (12h).
56
+ /**
57
+ * Adds a new Mulingstream chunk to the array stored at [${roomId}].
58
+ */
38
59
  async addMulingstreamChunk(params) {
39
60
  const { roomId, chunkNumber, language, start, end, duration, isFirst, isLast, theme, sttProviders, targetLanguages } = params;
40
- const mulingstreamChunkId = `[${roomId}]-[${chunkNumber}]-[${(0, uuid_1.v4)()}]`;
41
- // Prepare the nested objects
61
+ // Build the chunk
42
62
  const audioChunk = {
43
63
  start,
44
64
  end,
@@ -48,16 +68,15 @@ class MulingstreamChunkManager {
48
68
  theme,
49
69
  processingStart: Date.now()
50
70
  };
51
- // Build the STT object
52
- // For each service in `services`, create { transcription: '', status: 'INIT' }
71
+ // Build stt object
53
72
  const stt = {};
54
- for (const service of sttProviders) {
55
- stt[service] = {
73
+ for (const svc of sttProviders) {
74
+ stt[svc] = {
56
75
  transcription: '',
57
76
  status: 'INIT'
58
77
  };
59
78
  }
60
- // Build translation & tts objects keyed by each target language
79
+ // Build translation and tts objects
61
80
  const translation = {};
62
81
  const tts = {};
63
82
  for (const lang of targetLanguages) {
@@ -71,217 +90,123 @@ class MulingstreamChunkManager {
71
90
  isEmitted: false
72
91
  };
73
92
  }
74
- // Root-level finalTranscription is empty initially
75
- const finalTranscription = '';
76
- // Store the data in a Redis hash
77
- await this.redisClient.hset(`mulingstreamChunk:${mulingstreamChunkId}`, {
78
- mulingstreamChunkId,
79
- roomId,
80
- chunkNumber: chunkNumber.toString(),
93
+ const newChunk = {
94
+ chunkNumber,
81
95
  language,
82
- sttProviders: JSON.stringify(sttProviders),
83
- targetLanguages: JSON.stringify(targetLanguages),
84
- finalTranscription,
85
- mulingstreamChunkStatus: 'INIT',
86
- mulingstreamChunkStep: 'RECEIVED',
87
- audioChunk: JSON.stringify(audioChunk),
88
- stt: JSON.stringify(stt),
89
- translation: JSON.stringify(translation),
90
- tts: JSON.stringify(tts)
91
- });
92
- // set expiration
93
- await this.redisClient.expire(`mulingstreamChunk:${mulingstreamChunkId}`, EXPIRATION);
94
- return mulingstreamChunkId;
95
- }
96
- // Retrieves all mulingstream chunks by scanning keys `mulingstreamChunk:*`.
97
- async getMulingstreamChunks() {
98
- const keys = await this.redisClient.keys('mulingstreamChunk:*');
99
- if (!keys || keys.length === 0) {
100
- return [];
101
- }
102
- const results = [];
103
- for (const key of keys) {
104
- const data = await this.redisClient.hgetall(key);
105
- if (data && data.mulingstreamChunkId) {
106
- results.push(this.parseHashData(data));
107
- }
108
- }
109
- return results;
110
- }
111
- // Retrieves a single mulingstream chunk by ID.
112
- async getMulingstreamChunk(mulingstreamChunkId) {
113
- const data = await this.redisClient.hgetall(`mulingstreamChunk:${mulingstreamChunkId}`);
114
- if (!data || !data.mulingstreamChunkId) {
115
- return null;
116
- }
117
- return this.parseHashData(data);
118
- }
119
- // Retrieves all mulingstream chunks for a specific room by pattern matching keys `mulingstreamChunk:[roomId]-*`.
120
- async getMulingstreamChunksByRoom(roomId) {
121
- const pattern = `mulingstreamChunk:[${roomId}]-*`;
122
- const keys = await this.redisClient.keys(pattern);
123
- if (!keys || keys.length === 0) {
124
- return [];
125
- }
126
- const results = [];
127
- for (const key of keys) {
128
- const data = await this.redisClient.hgetall(key);
129
- if (!data || !data.mulingstreamChunkId) {
130
- continue;
131
- }
132
- results.push(this.parseHashData(data));
133
- }
134
- return results;
96
+ sttProviders,
97
+ targetLanguages,
98
+ finalTranscription: '',
99
+ sttStatus: 'INIT',
100
+ audioChunk,
101
+ stt,
102
+ translation,
103
+ tts
104
+ };
105
+ // Append it to the array
106
+ await this.redisClient.jsonArrAppend(`[${roomId}]`, '.', // the root of the JSON document (the array)
107
+ newChunk);
135
108
  }
136
- // Retrieves a mulingstream chunk by (roomId, chunkNumber).
137
- // Since mulingstreamChunkId = `[${roomId}]-[${chunkNumber}]-[uuid]`, we can pattern-match on keys.
138
- async getByChunkNumber(chunkNumber, roomId) {
139
- const pattern = `mulingstreamChunk:[${roomId}]-[${chunkNumber}]-*`;
140
- const keys = await this.redisClient.keys(pattern);
141
- if (!keys || keys.length === 0) {
109
+ /**
110
+ * Given roomId and chunkNumber, return the single chunk from the array
111
+ * or null if not found.
112
+ */
113
+ async getMulingstreamChunkById(roomId, chunkNumber) {
114
+ // Retrieve the entire array
115
+ const chunks = await this.getMulingstreamChunksByRoom(roomId);
116
+ if (!chunks)
142
117
  return null;
143
- }
144
- // If multiple match, return the first
145
- const data = await this.redisClient.hgetall(keys[0]);
146
- if (!data || !data.mulingstreamChunkId) {
147
- return null;
148
- }
149
- return this.parseHashData(data);
150
- }
151
- async updateMulingstreamChunkStatus(mulingstreamChunkId, mulingstreamChunkStep, mulingstreamChunkStatus) {
152
- // Fetch the chunk data first
153
- const data = await this.redisClient.hgetall(`mulingstreamChunk:${mulingstreamChunkId}`);
154
- if (!data || !data.mulingstreamChunkId) {
155
- return false; // The chunk may not exist or has expired
156
- }
157
- // Update only the chunk status and step
158
- await this.redisClient.hset(`mulingstreamChunk:${mulingstreamChunkId}`, {
159
- mulingstreamChunkStatus,
160
- mulingstreamChunkStep
161
- });
162
- return true;
118
+ // Find by chunkNumber
119
+ const chunk = chunks.find((c) => c.chunkNumber === chunkNumber);
120
+ return chunk || null;
163
121
  }
164
- async updateFinalTranscription(mulingstreamChunkId, finalTranscription) {
165
- // Fetch the chunk data first
166
- const data = await this.redisClient.hgetall(`mulingstreamChunk:${mulingstreamChunkId}`);
167
- if (!data || !data.mulingstreamChunkId) {
168
- return false; // The chunk may not exist or has expired
169
- }
170
- // Update the finalTranscription field
171
- await this.redisClient.hset(`mulingstreamChunk:${mulingstreamChunkId}`, {
172
- finalTranscription
173
- });
174
- return true;
175
- }
176
- // Updates the STT status for a given service in the chunk's STT data.
177
- async updateSttStatus(mulingstreamChunkId, service, status) {
178
- const data = await this.redisClient.hgetall(`mulingstreamChunk:${mulingstreamChunkId}`);
179
- if (!data || !data.mulingstreamChunkId) {
122
+ /**
123
+ * Update STT fields for a given chunk.
124
+ * If transcription or sttStatus is null, skip that field.
125
+ */
126
+ async updateStt(roomId, chunkNumber, sttProvider, options) {
127
+ const chunks = await this.getMulingstreamChunksByRoom(roomId);
128
+ if (!chunks)
180
129
  return false;
181
- }
182
- const stt = JSON.parse(data.stt);
183
- if (!stt[service]) {
184
- return false; // service not in stt object
185
- }
186
- stt[service].status = status;
187
- await this.redisClient.hset(`mulingstreamChunk:${mulingstreamChunkId}`, {
188
- stt: JSON.stringify(stt)
189
- });
190
- return true;
191
- }
192
- // Updates the transcription + status for a given service in the chunk's STT data.
193
- async updateTranscription(mulingstreamChunkId, service, transcription, sttStatus) {
194
- const data = await this.redisClient.hgetall(`mulingstreamChunk:${mulingstreamChunkId}`);
195
- if (!data || !data.mulingstreamChunkId) {
130
+ // Find the chunk
131
+ const chunkIndex = chunks.findIndex((c) => c.chunkNumber === chunkNumber);
132
+ if (chunkIndex === -1)
196
133
  return false;
134
+ const chunk = chunks[chunkIndex];
135
+ // If this stt provider doesn't exist, ignore
136
+ if (!chunk.stt[sttProvider])
137
+ return false;
138
+ // Update
139
+ if (options.transcription != null) {
140
+ chunk.stt[sttProvider].transcription = options.transcription;
197
141
  }
198
- const stt = JSON.parse(data.stt);
199
- if (!stt[service]) {
200
- return false; // service not in stt object
142
+ if (options.sttStatus != null) {
143
+ chunk.stt[sttProvider].status = options.sttStatus;
201
144
  }
202
- stt[service].transcription = transcription;
203
- stt[service].status = sttStatus;
204
- await this.redisClient.hset(`mulingstreamChunk:${mulingstreamChunkId}`, {
205
- stt: JSON.stringify(stt)
206
- });
145
+ // Write back
146
+ chunks[chunkIndex] = chunk;
147
+ await this.redisClient.jsonSet(`[${roomId}]`, '.', chunks);
207
148
  return true;
208
149
  }
209
- /****
210
- * Discards all post-STT steps for a given chunk, i.e. sets
211
- * all translation[].status and all tts[].status to "DISCARDED".
212
- ****/
213
- async discardAllPostStt(mulingstreamChunkId) {
214
- // Fetch the chunk
215
- const data = await this.redisClient.hgetall(`mulingstreamChunk:${mulingstreamChunkId}`);
216
- if (!data || !data.mulingstreamChunkId) {
150
+ /**
151
+ * Update the final transcription field for a chunk.
152
+ */
153
+ async updateFinalTranscription(roomId, chunkNumber, transcription, sttStatus) {
154
+ const chunks = await this.getMulingstreamChunksByRoom(roomId);
155
+ if (!chunks)
217
156
  return false;
218
- }
219
- // Parse the translation and tts objects
220
- const translation = JSON.parse(data.translation);
221
- const tts = JSON.parse(data.tts);
222
- // Set every language status to DISCARDED in translation
223
- for (const lang of Object.keys(translation)) {
224
- translation[lang].status = 'DISCARDED';
225
- }
226
- // Set every language status to DISCARDED in tts
227
- for (const lang of Object.keys(tts)) {
228
- tts[lang].status = 'DISCARDED';
229
- }
157
+ // Find the chunk
158
+ const chunkIndex = chunks.findIndex((c) => c.chunkNumber === chunkNumber);
159
+ if (chunkIndex === -1)
160
+ return false;
161
+ chunks[chunkIndex].finalTranscription = transcription;
162
+ chunks[chunkIndex].sttStatus = sttStatus;
230
163
  // Write back
231
- await this.redisClient.hset(`mulingstreamChunk:${mulingstreamChunkId}`, {
232
- translation: JSON.stringify(translation),
233
- tts: JSON.stringify(tts)
234
- });
164
+ await this.redisClient.jsonSet(`[${roomId}]`, '.', chunks);
235
165
  return true;
236
166
  }
237
- /****
238
- * Discards all post-translation steps for a given chunk, i.e. sets
239
- * all tts[].status to "DISCARDED" (leaves translation alone).
240
- ****/
241
- async discardAllPostTranslation(mulingstreamChunkId) {
242
- // Fetch the chunk
243
- const data = await this.redisClient.hgetall(`mulingstreamChunk:${mulingstreamChunkId}`);
244
- if (!data || !data.mulingstreamChunkId) {
167
+ /**
168
+ * Discards all post-STT steps for a given chunk:
169
+ * sets all translation[].status & tts[].status to "DISCARDED".
170
+ */
171
+ async discardPostStt(roomId, chunkNumber) {
172
+ const chunks = await this.getMulingstreamChunksByRoom(roomId);
173
+ if (!chunks)
174
+ return false;
175
+ // Find chunk
176
+ const chunkIndex = chunks.findIndex((c) => c.chunkNumber === chunkNumber);
177
+ if (chunkIndex === -1)
245
178
  return false;
179
+ // Discard translation & TTS statuses
180
+ const chunk = chunks[chunkIndex];
181
+ for (const lang of Object.keys(chunk.translation)) {
182
+ chunk.translation[lang].status = 'DISCARDED';
246
183
  }
247
- // Parse the tts object
248
- const tts = JSON.parse(data.tts);
249
- // Set every language status to DISCARDED in tts
250
- for (const lang of Object.keys(tts)) {
251
- tts[lang].status = 'DISCARDED';
184
+ for (const lang of Object.keys(chunk.tts)) {
185
+ chunk.tts[lang].status = 'DISCARDED';
252
186
  }
253
- // Write back
254
- await this.redisClient.hset(`mulingstreamChunk:${mulingstreamChunkId}`, {
255
- tts: JSON.stringify(tts)
256
- });
187
+ chunks[chunkIndex] = chunk;
188
+ await this.redisClient.jsonSet(`[${roomId}]`, '.', chunks);
257
189
  return true;
258
190
  }
259
- /****
260
- * Discards a specific language in both the translation and tts objects,
261
- * setting status to DISCARDED for just that one language.
262
- ****/
263
- async discardLanguage(mulingstreamChunkId, language) {
264
- // Fetch the chunk
265
- const data = await this.redisClient.hgetall(`mulingstreamChunk:${mulingstreamChunkId}`);
266
- if (!data || !data.mulingstreamChunkId) {
191
+ /**
192
+ * Discards a specific language in both translation and tts for a chunk.
193
+ */
194
+ async discardLanguage(roomId, chunkNumber, language) {
195
+ const chunks = await this.getMulingstreamChunksByRoom(roomId);
196
+ if (!chunks)
267
197
  return false;
198
+ const chunkIndex = chunks.findIndex((c) => c.chunkNumber === chunkNumber);
199
+ if (chunkIndex === -1)
200
+ return false;
201
+ const chunk = chunks[chunkIndex];
202
+ if (chunk.translation[language]) {
203
+ chunk.translation[language].status = 'DISCARDED';
268
204
  }
269
- // Parse the translation and tts objects
270
- const translation = JSON.parse(data.translation);
271
- const tts = JSON.parse(data.tts);
272
- // If the language exists in translation, discard
273
- if (translation[language]) {
274
- translation[language].status = 'DISCARDED';
275
- }
276
- // If the language exists in tts, discard
277
- if (tts[language]) {
278
- tts[language].status = 'DISCARDED';
205
+ if (chunk.tts[language]) {
206
+ chunk.tts[language].status = 'DISCARDED';
279
207
  }
280
- // Write back
281
- await this.redisClient.hset(`mulingstreamChunk:${mulingstreamChunkId}`, {
282
- translation: JSON.stringify(translation),
283
- tts: JSON.stringify(tts)
284
- });
208
+ chunks[chunkIndex] = chunk;
209
+ await this.redisClient.jsonSet(`[${roomId}]`, '.', chunks);
285
210
  return true;
286
211
  }
287
212
  }
@@ -19,4 +19,8 @@ export declare class RedisClient {
19
19
  flushAll(): Promise<string>;
20
20
  flushDb(): Promise<string>;
21
21
  expire(key: string, seconds: number): Promise<number>;
22
+ jsonSet<T>(key: string, path: string, value: T): Promise<string>;
23
+ jsonGet<T>(key: string, path: string): Promise<T | null>;
24
+ jsonDel(key: string, path: string): Promise<number>;
25
+ jsonArrAppend<T>(key: string, path: string, ...values: T[]): Promise<number>;
22
26
  }
@@ -61,5 +61,25 @@ class RedisClient {
61
61
  async expire(key, seconds) {
62
62
  return this.client.expire(key, seconds);
63
63
  }
64
+ async jsonSet(key, path, value) {
65
+ const result = await this.client.call('JSON.SET', key, path, JSON.stringify(value));
66
+ return result;
67
+ }
68
+ async jsonGet(key, path) {
69
+ const result = (await this.client.call('JSON.GET', key, path));
70
+ if (!result) {
71
+ return null;
72
+ }
73
+ return JSON.parse(result);
74
+ }
75
+ async jsonDel(key, path) {
76
+ const result = await this.client.call('JSON.DEL', key, path);
77
+ return Number(result);
78
+ }
79
+ async jsonArrAppend(key, path, ...values) {
80
+ const stringifiedValues = values.map((v) => JSON.stringify(v));
81
+ const result = await this.client.call('JSON.ARRAPPEND', key, path, ...stringifiedValues);
82
+ return Number(result);
83
+ }
64
84
  }
65
85
  exports.RedisClient = RedisClient;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mulingai-npm/redis",
3
- "version": "1.14.1",
3
+ "version": "2.0.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "repository": {