@mulingai-npm/redis 3.2.2 → 3.4.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.
@@ -7,6 +7,7 @@ export interface ChunkLogOptions {
7
7
  processLength?: boolean;
8
8
  finalTranscription?: boolean;
9
9
  sttStatus?: boolean;
10
+ audioFilePath?: boolean;
10
11
  stt?: boolean;
11
12
  translation?: boolean;
12
13
  tts?: boolean;
@@ -5,6 +5,7 @@ const mulingstream_chunk_manager_1 = require("../managers/mulingstream-chunk-man
5
5
  const defaults = {
6
6
  chunkId: false,
7
7
  chunkNumber: true,
8
+ audioFilePath: true,
8
9
  roomId: false,
9
10
  processLength: false,
10
11
  language: false,
@@ -61,6 +62,8 @@ class MulingstreamChunkLogger extends mulingstream_chunk_manager_1.MulingstreamC
61
62
  out.roomId = chunk.roomId;
62
63
  if (o.chunkNumber)
63
64
  out.chunkNumber = chunk.chunkNumber;
65
+ if (o.audioFilePath)
66
+ out.audioFilePath = chunk.audioChunk.audioFilePath;
64
67
  if (o.processLength)
65
68
  out.processLength = Date.now() - chunk.createdAt + 'ms';
66
69
  if (o.language)
@@ -22,8 +22,7 @@ export type MulingstreamChunkData = {
22
22
  duration: number;
23
23
  isFirst: boolean;
24
24
  isLast: boolean;
25
- theme: string;
26
- processingStart: number;
25
+ audioFilePath: string;
27
26
  };
28
27
  stt: {
29
28
  [service: string]: {
@@ -43,7 +42,6 @@ export type MulingstreamChunkData = {
43
42
  ttsAudioPath: string;
44
43
  status: StepStatus;
45
44
  isEmitted: boolean;
46
- totalCheck: number;
47
45
  };
48
46
  };
49
47
  };
@@ -70,46 +68,44 @@ export declare class MulingstreamChunkManager {
70
68
  duration: number;
71
69
  isFirst: boolean;
72
70
  isLast: boolean;
73
- theme: string;
74
71
  sttProviders: SttProvider[];
75
72
  targetLanguages: string[];
76
73
  shortCodeTargetLanguages: string[];
77
- }): Promise<void>;
74
+ }): Promise<MulingstreamChunkData>;
78
75
  private getChunkId;
79
76
  getMulingstreamChunkById(roomId: string, n: number): Promise<MulingstreamChunkData>;
80
77
  private withChunk;
78
+ updateAudioFilePath(roomId: string, chunkNumber: number, audioFilePath: string): Promise<MulingstreamChunkData | null>;
81
79
  updateStt(roomId: string, n: number, service: SttService, opt: {
82
80
  transcription?: string;
83
81
  sttStatus?: StepStatus;
84
- }): Promise<boolean>;
82
+ }): Promise<MulingstreamChunkData | null>;
85
83
  updateSttObject(roomId: string, n: number, newStt: Record<string, {
86
84
  transcription: string;
87
85
  model?: string;
88
86
  status: StepStatus;
89
- }>): Promise<boolean>;
90
- discardStt(roomId: string, n: number): Promise<boolean>;
87
+ }>): Promise<MulingstreamChunkData | null>;
88
+ discardStt(roomId: string, n: number): Promise<MulingstreamChunkData | null>;
91
89
  updateFinalTranscription(roomId: string, n: number, opt: {
92
90
  transcription?: string;
93
91
  sttStatus?: StepStatus;
94
- }): Promise<MulingstreamChunkData>;
95
- discardPostStt(roomId: string, n: number): Promise<boolean>;
96
- discardLanguage(roomId: string, n: number, lang: string): Promise<boolean>;
92
+ }): Promise<MulingstreamChunkData | null>;
93
+ discardPostStt(roomId: string, n: number): Promise<MulingstreamChunkData | null>;
94
+ discardLanguage(roomId: string, n: number, lang: string): Promise<MulingstreamChunkData | null>;
97
95
  discardLanguages(roomId: string, n: number, opt: {
98
96
  translation?: string[];
99
97
  tts?: string[];
100
- }): Promise<MulingstreamChunkData>;
98
+ }): Promise<MulingstreamChunkData | null>;
101
99
  updateTranslation(roomId: string, n: number, lang: string, opt: {
102
100
  translation?: string;
103
101
  status?: StepStatus;
104
- }): Promise<MulingstreamChunkData>;
105
- updateTranslationInBulk(roomId: string, n: number, dict: Record<string, string>, status?: StepStatus): Promise<MulingstreamChunkData>;
102
+ }): Promise<MulingstreamChunkData | null>;
103
+ updateTranslationInBulk(roomId: string, n: number, dict: Record<string, string>, status?: StepStatus): Promise<MulingstreamChunkData | null>;
106
104
  updateTts(roomId: string, n: number, lang: string, opt: {
107
105
  ttsAudioPath?: string;
108
106
  status?: StepStatus;
109
107
  isEmitted?: boolean;
110
- totalCheck?: number;
111
- }): Promise<MulingstreamChunkData>;
112
- increaseTotalCheck(roomId: string, n: number, lang: string): Promise<MulingstreamChunkData>;
108
+ }): Promise<MulingstreamChunkData | null>;
113
109
  areTranslationsProcessed(roomId: string, n: number): Promise<boolean>;
114
110
  getAllReadyTts(roomId: string, lang: string): Promise<MulingstreamChunkData[]>;
115
111
  }
@@ -2,19 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MulingstreamChunkManager = void 0;
4
4
  const uuid_1 = require("uuid");
5
- /* -------------------------------------------------------------------------- */
6
- /* Constants */
7
- /* -------------------------------------------------------------------------- */
8
- const EXPIRATION = 12 * 60 * 60; // 12 h
9
- const ROOM_ARRAY_LENGTH = 50; // keep last 50 chunks
10
- /* -------------------------------------------------------------------------- */
11
- /* Main class */
12
- /* -------------------------------------------------------------------------- */
5
+ const EXPIRATION = 12 * 60 * 60;
6
+ const ROOM_ARRAY_LENGTH = 50;
13
7
  class MulingstreamChunkManager {
14
8
  constructor(redisClient) {
15
9
  this.redisClient = redisClient;
16
10
  }
17
- /* ----------------------------- key helpers ----------------------------- */
18
11
  roomZsetKey(roomId) {
19
12
  return `room:${roomId}:chunks`;
20
13
  }
@@ -24,7 +17,6 @@ class MulingstreamChunkManager {
24
17
  generateChunkId(roomId, chunkNumber) {
25
18
  return `[${roomId}]-[${chunkNumber}]-[${(0, uuid_1.v4)()}]`;
26
19
  }
27
- /* --------------------------- (de)serialization -------------------------- */
28
20
  serialize(value) {
29
21
  return JSON.stringify(value);
30
22
  }
@@ -49,14 +41,9 @@ class MulingstreamChunkManager {
49
41
  tts: this.deserialize(h.tts)
50
42
  };
51
43
  }
52
- /* ------------------------------ timeouts ------------------------------- */
53
44
  getTimeout(start, end) {
54
- return 30000;
45
+ return 25000;
55
46
  }
56
- /* ---------------------------------------------------------------------- */
57
- /* Public API (same) */
58
- /* ---------------------------------------------------------------------- */
59
- /* Room helpers ---------------------------------------------------------- */
60
47
  async initRoom(roomId) {
61
48
  const exists = await this.redisClient.exists(this.roomZsetKey(roomId));
62
49
  if (exists)
@@ -82,10 +69,9 @@ class MulingstreamChunkManager {
82
69
  getRoomById(roomId) {
83
70
  return this.getMulingstreamChunksByRoom(roomId);
84
71
  }
85
- /* ------------------------- chunk insertion ---------------------------- */
86
72
  async addMulingstreamChunk(params) {
87
73
  var _a, _b;
88
- const { roomId, chunkNumber, language, start, end, duration, isFirst, isLast, theme, sttProviders, targetLanguages, shortCodeTargetLanguages } = params;
74
+ const { roomId, chunkNumber, language, start, end, duration, isFirst, isLast, sttProviders, targetLanguages, shortCodeTargetLanguages } = params;
89
75
  if (chunkNumber === 1) {
90
76
  const old = await this.redisClient.zrange(this.roomZsetKey(roomId), 0, -1);
91
77
  if (old.length) {
@@ -105,15 +91,32 @@ class MulingstreamChunkManager {
105
91
  }
106
92
  }
107
93
  const chunkId = this.generateChunkId(roomId, chunkNumber);
108
- const audioChunk = { start, end, duration, isFirst, isLast, theme, processingStart: Date.now() };
94
+ const audioChunk = { start, end, duration, isFirst, isLast, audioFilePath: '' };
109
95
  const stt = {};
110
96
  sttProviders.forEach((p) => (stt[p.service] = { transcription: '', model: p.model, status: 'INIT' }));
111
97
  const translation = {};
112
98
  const tts = {};
113
99
  shortCodeTargetLanguages.forEach((l) => {
114
100
  translation[l] = { translation: '', status: 'INIT' };
115
- tts[l] = { ttsAudioPath: '', status: 'INIT', isEmitted: false, totalCheck: 0 };
101
+ tts[l] = { ttsAudioPath: '', status: 'INIT', isEmitted: false };
116
102
  });
103
+ const createdAt = Date.now();
104
+ const chunk = {
105
+ chunkId,
106
+ roomId,
107
+ chunkNumber,
108
+ language,
109
+ sttProviders,
110
+ targetLanguages,
111
+ shortCodeTargetLanguages,
112
+ finalTranscription: '',
113
+ sttStatus: 'INIT',
114
+ createdAt,
115
+ audioChunk,
116
+ stt,
117
+ translation,
118
+ tts
119
+ };
117
120
  const hash = {
118
121
  chunkId,
119
122
  roomId,
@@ -124,7 +127,7 @@ class MulingstreamChunkManager {
124
127
  shortCodeTargetLanguages: this.serialize(shortCodeTargetLanguages),
125
128
  finalTranscription: '',
126
129
  sttStatus: 'INIT',
127
- createdAt: String(Date.now()),
130
+ createdAt: String(createdAt),
128
131
  audioChunk: this.serialize(audioChunk),
129
132
  stt: this.serialize(stt),
130
133
  translation: this.serialize(translation),
@@ -147,8 +150,8 @@ class MulingstreamChunkManager {
147
150
  oldIds.forEach((cid) => trim.unlink(this.chunkHashKey(cid)));
148
151
  await trim.exec();
149
152
  }
153
+ return chunk;
150
154
  }
151
- /* --------------------------- helper lookup ---------------------------- */
152
155
  async getChunkId(roomId, n) {
153
156
  const ids = await this.redisClient.zrangebyscore(this.roomZsetKey(roomId), n, n);
154
157
  return ids.length ? ids[0] : null;
@@ -160,8 +163,6 @@ class MulingstreamChunkManager {
160
163
  const raw = await this.redisClient.hgetall(this.chunkHashKey(cid));
161
164
  return raw.chunkId ? this.hashToChunk(raw) : null;
162
165
  }
163
- /* ------------------------------ Updaters ------------------------------ */
164
- /* helper to fetch-mutate-save one chunk */
165
166
  async withChunk(roomId, n, fn) {
166
167
  const cid = await this.getChunkId(roomId, n);
167
168
  if (!cid)
@@ -171,46 +172,49 @@ class MulingstreamChunkManager {
171
172
  if (!raw.chunkId)
172
173
  return null;
173
174
  const chunk = this.hashToChunk(raw);
174
- const out = await fn(chunk);
175
+ await fn(chunk);
175
176
  const p = this.redisClient.pipeline();
176
177
  p.hset(key, {
177
178
  finalTranscription: chunk.finalTranscription,
178
179
  sttStatus: chunk.sttStatus,
179
180
  stt: this.serialize(chunk.stt),
180
181
  translation: this.serialize(chunk.translation),
181
- tts: this.serialize(chunk.tts)
182
+ tts: this.serialize(chunk.tts),
183
+ audioChunk: this.serialize(chunk.audioChunk)
182
184
  });
183
185
  p.expire(key, EXPIRATION);
184
186
  await p.exec();
185
- return out;
187
+ return chunk;
188
+ }
189
+ async updateAudioFilePath(roomId, chunkNumber, audioFilePath) {
190
+ return this.withChunk(roomId, chunkNumber, (chunk) => {
191
+ chunk.audioChunk.audioFilePath = audioFilePath;
192
+ });
186
193
  }
187
194
  async updateStt(roomId, n, service, opt) {
188
- return ((await this.withChunk(roomId, n, (c) => {
195
+ return this.withChunk(roomId, n, (c) => {
189
196
  if (!c.stt[service])
190
- return false;
197
+ return;
191
198
  if (opt.transcription !== undefined)
192
199
  c.stt[service].transcription = opt.transcription;
193
200
  if (opt.sttStatus !== undefined)
194
201
  c.stt[service].status = opt.sttStatus;
195
- return true;
196
- })) === true);
202
+ });
197
203
  }
198
204
  async updateSttObject(roomId, n, newStt) {
199
- return ((await this.withChunk(roomId, n, (c) => {
205
+ return this.withChunk(roomId, n, (c) => {
200
206
  c.stt = newStt;
201
- return true;
202
- })) === true);
207
+ });
203
208
  }
204
209
  async discardStt(roomId, n) {
205
- return ((await this.withChunk(roomId, n, (c) => {
210
+ return this.withChunk(roomId, n, (c) => {
206
211
  Object.keys(c.stt).forEach((p) => {
207
212
  c.stt[p].transcription = '';
208
213
  c.stt[p].status = 'DISCARDED';
209
214
  });
210
215
  c.finalTranscription = '';
211
216
  c.sttStatus = 'DISCARDED';
212
- return true;
213
- })) === true);
217
+ });
214
218
  }
215
219
  async updateFinalTranscription(roomId, n, opt) {
216
220
  return this.withChunk(roomId, n, (c) => {
@@ -218,24 +222,21 @@ class MulingstreamChunkManager {
218
222
  c.finalTranscription = opt.transcription;
219
223
  if (opt.sttStatus !== undefined)
220
224
  c.sttStatus = opt.sttStatus;
221
- return c;
222
225
  });
223
226
  }
224
227
  async discardPostStt(roomId, n) {
225
- return ((await this.withChunk(roomId, n, (c) => {
228
+ return this.withChunk(roomId, n, (c) => {
226
229
  Object.values(c.translation).forEach((t) => (t.status = 'DISCARDED'));
227
230
  Object.values(c.tts).forEach((t) => (t.status = 'DISCARDED'));
228
- return true;
229
- })) === true);
231
+ });
230
232
  }
231
233
  async discardLanguage(roomId, n, lang) {
232
- return ((await this.withChunk(roomId, n, (c) => {
234
+ return this.withChunk(roomId, n, (c) => {
233
235
  if (c.translation[lang])
234
236
  c.translation[lang].status = 'DISCARDED';
235
237
  if (c.tts[lang])
236
238
  c.tts[lang].status = 'DISCARDED';
237
- return true;
238
- })) === true);
239
+ });
239
240
  }
240
241
  async discardLanguages(roomId, n, opt) {
241
242
  return this.withChunk(roomId, n, (c) => {
@@ -250,19 +251,17 @@ class MulingstreamChunkManager {
250
251
  if (e && e.status === 'INIT')
251
252
  e.status = 'DISCARDED';
252
253
  });
253
- return c;
254
254
  });
255
255
  }
256
256
  async updateTranslation(roomId, n, lang, opt) {
257
257
  return this.withChunk(roomId, n, (c) => {
258
258
  const e = c.translation[lang];
259
259
  if (!e)
260
- return null;
260
+ return;
261
261
  if (opt.translation !== undefined)
262
262
  e.translation = opt.translation;
263
263
  if (opt.status !== undefined)
264
264
  e.status = opt.status;
265
- return c;
266
265
  });
267
266
  }
268
267
  async updateTranslationInBulk(roomId, n, dict, status = 'READY') {
@@ -273,38 +272,25 @@ class MulingstreamChunkManager {
273
272
  c.translation[l].translation = txt;
274
273
  c.translation[l].status = status;
275
274
  });
276
- return c;
277
275
  });
278
276
  }
279
277
  async updateTts(roomId, n, lang, opt) {
280
278
  return this.withChunk(roomId, n, (c) => {
281
279
  const e = c.tts[lang];
282
280
  if (!e)
283
- return null;
281
+ return;
284
282
  if (opt.ttsAudioPath !== undefined)
285
283
  e.ttsAudioPath = opt.ttsAudioPath;
286
284
  if (opt.status !== undefined)
287
285
  e.status = opt.status;
288
286
  if (opt.isEmitted !== undefined)
289
287
  e.isEmitted = opt.isEmitted;
290
- if (opt.totalCheck !== undefined)
291
- e.totalCheck = opt.totalCheck;
292
- return c;
293
- });
294
- }
295
- async increaseTotalCheck(roomId, n, lang) {
296
- return this.withChunk(roomId, n, (c) => {
297
- if (!c.tts[lang])
298
- return null;
299
- c.tts[lang].totalCheck += 1;
300
- return c;
301
288
  });
302
289
  }
303
290
  async areTranslationsProcessed(roomId, n) {
304
291
  const c = await this.getMulingstreamChunkById(roomId, n);
305
292
  return !!c && Object.values(c.translation).every((t) => t.status !== 'INIT');
306
293
  }
307
- /* -------------------------- READY-TTS sequence ------------------------- */
308
294
  async getAllReadyTts(roomId, lang) {
309
295
  var _a;
310
296
  const chunks = (_a = (await this.getMulingstreamChunksByRoom(roomId))) !== null && _a !== void 0 ? _a : [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mulingai-npm/redis",
3
- "version": "3.2.2",
3
+ "version": "3.4.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "repository": {