@eka-care/ekascribe-ts-sdk 1.5.87 → 1.5.89
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/dist/api/config/get-voice-api-v2-config-my-templates.js +22 -12
- package/dist/api/config/get-voice-api-v2-config.js +22 -12
- package/dist/api/config/patch-voice-api-v2-config.js +21 -13
- package/dist/api/post-cog-init.js +28 -15
- package/dist/api/post-v1-file-upload.js +38 -28
- package/dist/api/template-sections/delete-v1-template-section.js +37 -27
- package/dist/api/template-sections/get-v1-template-sections.js +37 -27
- package/dist/api/template-sections/patch-v1-template-section.js +46 -36
- package/dist/api/template-sections/post-v1-template-section.js +45 -35
- package/dist/api/templates/cook-v1-medai-ai-create-template.js +35 -25
- package/dist/api/templates/delete-v1-template.js +37 -27
- package/dist/api/templates/get-v1-templates.js +37 -27
- package/dist/api/templates/patch-v1-template.js +44 -33
- package/dist/api/templates/post-convert-transcription-to-template.js +41 -31
- package/dist/api/templates/post-transaction-convert-to-template.js +38 -28
- package/dist/api/templates/post-v1-template.js +43 -33
- package/dist/api/transaction/get-transaction-history.js +20 -9
- package/dist/api/transaction/get-voice-api-v3-status-transcript.js +21 -8
- package/dist/api/transaction/get-voice-api-v3-status.js +21 -8
- package/dist/api/transaction/patch-transaction-status.js +23 -14
- package/dist/api/transaction/patch-voice-api-v3-status.js +22 -12
- package/dist/api/transaction/post-transaction-commit.js +41 -31
- package/dist/api/transaction/post-transaction-init.js +52 -47
- package/dist/api/transaction/post-transaction-stop.js +41 -31
- package/dist/api/upload-audio-with-presigned-url.js +67 -55
- package/dist/audio-chunker/audio-buffer-manager.js +5 -3
- package/dist/audio-chunker/audio-file-manager.js +353 -350
- package/dist/audio-chunker/vad-web.js +116 -97
- package/dist/aws-services/configure-aws.js +5 -2
- package/dist/aws-services/get-files-s3.js +20 -7
- package/dist/aws-services/s3-retry-wrapper.js +44 -31
- package/dist/aws-services/translate-text-to-target-language.js +28 -15
- package/dist/aws-services/upload-file-to-s3.js +17 -6
- package/dist/constants/constant.js +22 -19
- package/dist/constants/enums.js +15 -12
- package/dist/constants/setup-config.js +10 -7
- package/dist/constants/types.d.ts +1 -1
- package/dist/constants/types.js +2 -1
- package/dist/fetch-client/helper.js +24 -11
- package/dist/fetch-client/index.js +61 -52
- package/dist/index.js +321 -254
- package/dist/main/end-recording.js +56 -53
- package/dist/main/init-transaction.js +36 -27
- package/dist/main/pause-recording.js +17 -18
- package/dist/main/poll-output-summary.js +21 -7
- package/dist/main/resume-recording.js +13 -14
- package/dist/main/retry-upload-recording.js +39 -30
- package/dist/main/start-recording.js +34 -26
- package/dist/main/upload-full-audio-with-presigned-url.js +84 -69
- package/dist/shared-worker/s3-file-upload.js +88 -79
- package/dist/shared-worker/s3-file-upload.ts +1 -1
- package/dist/store/store.js +3 -1
- package/dist/utils/compress-mp3-audio.d.ts +1 -1
- package/dist/utils/compress-mp3-audio.js +6 -4
- package/dist/utils/get-worker-url.js +12 -7
- package/dist/utils/search-past-sessions.js +23 -9
- package/package.json +1 -1
|
@@ -1,12 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const constant_1 = require("../constants/constant");
|
|
13
|
+
const upload_file_to_s3_1 = require("../aws-services/upload-file-to-s3");
|
|
14
|
+
const post_cog_init_1 = require("../api/post-cog-init");
|
|
15
|
+
const configure_aws_1 = require("../aws-services/configure-aws");
|
|
16
|
+
const enums_1 = require("../constants/enums");
|
|
17
|
+
const compress_mp3_audio_1 = require("../utils/compress-mp3-audio");
|
|
18
|
+
const store_1 = require("../store/store");
|
|
19
|
+
const helper_1 = require("../fetch-client/helper");
|
|
20
|
+
const get_worker_url_1 = require("../utils/get-worker-url");
|
|
10
21
|
class AudioFileManager {
|
|
11
22
|
initialiseClassInstance() {
|
|
12
23
|
this.audioChunks = [];
|
|
@@ -138,17 +149,17 @@ class AudioFileManager {
|
|
|
138
149
|
// const worker = new SharedWorker(
|
|
139
150
|
// 'https://unpkg.com/@eka-care/ekascribe-ts-sdk@1.5.80/dist/shared-worker/s3-file-upload.js'
|
|
140
151
|
// );
|
|
141
|
-
const workerUrl = getSharedWorkerUrl();
|
|
152
|
+
const workerUrl = (0, get_worker_url_1.getSharedWorkerUrl)();
|
|
142
153
|
const worker = new SharedWorker(workerUrl);
|
|
143
154
|
this.sharedWorkerInstance = worker;
|
|
144
|
-
const onEventCallback =
|
|
145
|
-
this.sharedWorkerInstance.port.onmessage =
|
|
155
|
+
const onEventCallback = store_1.default.eventCallback;
|
|
156
|
+
this.sharedWorkerInstance.port.onmessage = (event) => __awaiter(this, void 0, void 0, function* () {
|
|
146
157
|
const workerResponse = event.data;
|
|
147
158
|
switch (workerResponse.action) {
|
|
148
|
-
case SHARED_WORKER_ACTION.CONFIGURE_AWS_SUCCESS: {
|
|
159
|
+
case enums_1.SHARED_WORKER_ACTION.CONFIGURE_AWS_SUCCESS: {
|
|
149
160
|
if (onEventCallback) {
|
|
150
161
|
onEventCallback({
|
|
151
|
-
callback_type: CALLBACK_TYPE.AWS_CONFIGURE_STATUS,
|
|
162
|
+
callback_type: enums_1.CALLBACK_TYPE.AWS_CONFIGURE_STATUS,
|
|
152
163
|
status: 'success',
|
|
153
164
|
message: workerResponse.message,
|
|
154
165
|
timestamp: new Date().toISOString(),
|
|
@@ -156,10 +167,10 @@ class AudioFileManager {
|
|
|
156
167
|
}
|
|
157
168
|
return;
|
|
158
169
|
}
|
|
159
|
-
case SHARED_WORKER_ACTION.CONFIGURE_AWS_ERROR: {
|
|
170
|
+
case enums_1.SHARED_WORKER_ACTION.CONFIGURE_AWS_ERROR: {
|
|
160
171
|
if (onEventCallback) {
|
|
161
172
|
onEventCallback({
|
|
162
|
-
callback_type: CALLBACK_TYPE.AWS_CONFIGURE_STATUS,
|
|
173
|
+
callback_type: enums_1.CALLBACK_TYPE.AWS_CONFIGURE_STATUS,
|
|
163
174
|
status: 'error',
|
|
164
175
|
message: workerResponse.message,
|
|
165
176
|
timestamp: new Date().toISOString(),
|
|
@@ -167,11 +178,11 @@ class AudioFileManager {
|
|
|
167
178
|
}
|
|
168
179
|
return;
|
|
169
180
|
}
|
|
170
|
-
case SHARED_WORKER_ACTION.UPLOAD_FILE_WITH_WORKER_SUCCESS: {
|
|
181
|
+
case enums_1.SHARED_WORKER_ACTION.UPLOAD_FILE_WITH_WORKER_SUCCESS: {
|
|
171
182
|
const { fileCount: fileName, chunkIndex, fileBlob, compressedAudioBuffer, } = workerResponse.requestBody;
|
|
172
183
|
if (onEventCallback && compressedAudioBuffer) {
|
|
173
184
|
onEventCallback({
|
|
174
|
-
callback_type: CALLBACK_TYPE.FILE_UPLOAD_STATUS,
|
|
185
|
+
callback_type: enums_1.CALLBACK_TYPE.FILE_UPLOAD_STATUS,
|
|
175
186
|
status: 'info',
|
|
176
187
|
message: 'Audioframes of chunk to store in IDB',
|
|
177
188
|
timestamp: new Date().toISOString(),
|
|
@@ -187,17 +198,11 @@ class AudioFileManager {
|
|
|
187
198
|
this.successfulUploads.push(fileName);
|
|
188
199
|
// remove audioFrames if file uploaded successfully
|
|
189
200
|
if (chunkIndex !== -1) {
|
|
190
|
-
this.audioChunks[chunkIndex] = {
|
|
191
|
-
...this.audioChunks[chunkIndex],
|
|
192
|
-
audioFrames: undefined,
|
|
193
|
-
fileBlob: undefined,
|
|
194
|
-
status: 'success',
|
|
195
|
-
response: workerResponse.response.success,
|
|
196
|
-
};
|
|
201
|
+
this.audioChunks[chunkIndex] = Object.assign(Object.assign({}, this.audioChunks[chunkIndex]), { audioFrames: undefined, fileBlob: undefined, status: 'success', response: workerResponse.response.success });
|
|
197
202
|
}
|
|
198
203
|
if (onEventCallback) {
|
|
199
204
|
onEventCallback({
|
|
200
|
-
callback_type: CALLBACK_TYPE.FILE_UPLOAD_STATUS,
|
|
205
|
+
callback_type: enums_1.CALLBACK_TYPE.FILE_UPLOAD_STATUS,
|
|
201
206
|
status: 'success',
|
|
202
207
|
message: workerResponse.response.success,
|
|
203
208
|
timestamp: new Date().toISOString(),
|
|
@@ -212,7 +217,7 @@ class AudioFileManager {
|
|
|
212
217
|
else {
|
|
213
218
|
if (onEventCallback) {
|
|
214
219
|
onEventCallback({
|
|
215
|
-
callback_type: CALLBACK_TYPE.FILE_UPLOAD_STATUS,
|
|
220
|
+
callback_type: enums_1.CALLBACK_TYPE.FILE_UPLOAD_STATUS,
|
|
216
221
|
status: 'error',
|
|
217
222
|
message: workerResponse.response.error || 'Upload failed',
|
|
218
223
|
timestamp: new Date().toISOString(),
|
|
@@ -229,13 +234,7 @@ class AudioFileManager {
|
|
|
229
234
|
}
|
|
230
235
|
// store that audioFrames in audioChunks
|
|
231
236
|
if (chunkIndex !== -1) {
|
|
232
|
-
this.audioChunks[chunkIndex] = {
|
|
233
|
-
...this.audioChunks[chunkIndex],
|
|
234
|
-
fileBlob,
|
|
235
|
-
audioFrames: undefined,
|
|
236
|
-
status: 'failure',
|
|
237
|
-
response: workerResponse.response.error || 'Upload failed',
|
|
238
|
-
};
|
|
237
|
+
this.audioChunks[chunkIndex] = Object.assign(Object.assign({}, this.audioChunks[chunkIndex]), { fileBlob, audioFrames: undefined, status: 'failure', response: workerResponse.response.error || 'Upload failed' });
|
|
239
238
|
}
|
|
240
239
|
// call COG if S3 throws ExpiredToken error
|
|
241
240
|
if (workerResponse.response.errorCode === 'ExpiredToken') {
|
|
@@ -246,7 +245,7 @@ class AudioFileManager {
|
|
|
246
245
|
}
|
|
247
246
|
}
|
|
248
247
|
}
|
|
249
|
-
};
|
|
248
|
+
});
|
|
250
249
|
worker.port.start();
|
|
251
250
|
return true;
|
|
252
251
|
}
|
|
@@ -264,229 +263,231 @@ class AudioFileManager {
|
|
|
264
263
|
return false;
|
|
265
264
|
}
|
|
266
265
|
}
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
266
|
+
setupAWSConfiguration(_a) {
|
|
267
|
+
return __awaiter(this, arguments, void 0, function* ({ is_shared_worker }) {
|
|
268
|
+
var _b;
|
|
269
|
+
try {
|
|
270
|
+
const response = yield (0, post_cog_init_1.default)();
|
|
271
|
+
const { credentials, is_session_expired } = response;
|
|
272
|
+
if (is_session_expired || !credentials) {
|
|
273
|
+
this.isAWSConfigured = false;
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
const { AccessKeyId, SecretKey, SessionToken } = credentials;
|
|
277
|
+
if (is_shared_worker) {
|
|
278
|
+
(_b = this.sharedWorkerInstance) === null || _b === void 0 ? void 0 : _b.port.postMessage({
|
|
279
|
+
action: enums_1.SHARED_WORKER_ACTION.CONFIGURE_AWS,
|
|
280
|
+
payload: {
|
|
281
|
+
accessKeyId: AccessKeyId,
|
|
282
|
+
secretKey: SecretKey,
|
|
283
|
+
sessionToken: SessionToken,
|
|
284
|
+
},
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
(0, configure_aws_1.configureAWS)({
|
|
280
289
|
accessKeyId: AccessKeyId,
|
|
281
290
|
secretKey: SecretKey,
|
|
282
291
|
sessionToken: SessionToken,
|
|
283
|
-
}
|
|
284
|
-
}
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
this.isAWSConfigured = true;
|
|
295
|
+
return true;
|
|
285
296
|
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
sessionToken: SessionToken,
|
|
291
|
-
});
|
|
297
|
+
catch (error) {
|
|
298
|
+
console.log('%c Line:198 🥃 error', 'color:#42b983', error);
|
|
299
|
+
this.isAWSConfigured = false;
|
|
300
|
+
return false;
|
|
292
301
|
}
|
|
293
|
-
|
|
294
|
-
return true;
|
|
295
|
-
}
|
|
296
|
-
catch (error) {
|
|
297
|
-
console.log('%c Line:198 🥃 error', 'color:#42b983', error);
|
|
298
|
-
this.isAWSConfigured = false;
|
|
299
|
-
return false;
|
|
300
|
-
}
|
|
302
|
+
});
|
|
301
303
|
}
|
|
302
304
|
/**
|
|
303
305
|
* Upload a chunk of audio data to S3 in main thread
|
|
304
306
|
*/
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
const onEventCallback = EkaScribeStore.eventCallback;
|
|
312
|
-
if (onEventCallback) {
|
|
313
|
-
onEventCallback({
|
|
314
|
-
callback_type: CALLBACK_TYPE.FILE_UPLOAD_STATUS,
|
|
315
|
-
status: 'info',
|
|
316
|
-
message: 'Audio chunks count to display success/total file count and to store chunks in IDB',
|
|
317
|
-
timestamp: new Date().toISOString(),
|
|
318
|
-
data: {
|
|
319
|
-
success: this.successfulUploads.length,
|
|
320
|
-
total: this.audioChunks.length,
|
|
321
|
-
fileName,
|
|
322
|
-
chunkData: compressedAudioBuffer,
|
|
323
|
-
},
|
|
307
|
+
uploadAudioChunkInMain(_a) {
|
|
308
|
+
return __awaiter(this, arguments, void 0, function* ({ audioFrames, fileName, chunkIndex, }) {
|
|
309
|
+
const s3FileName = `${this.filePath}/${fileName}`; // fileName is ${fileCount}.mp3
|
|
310
|
+
const compressedAudioBuffer = (0, compress_mp3_audio_1.default)(audioFrames);
|
|
311
|
+
const audioBlob = new Blob(compressedAudioBuffer, {
|
|
312
|
+
type: constant_1.AUDIO_EXTENSION_TYPE_MAP[constant_1.OUTPUT_FORMAT],
|
|
324
313
|
});
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
// update file status if file uploaded successfully
|
|
340
|
-
if (chunkIndex !== -1) {
|
|
341
|
-
this.audioChunks[chunkIndex] = {
|
|
342
|
-
...this.audioChunks[chunkIndex],
|
|
343
|
-
audioFrames: undefined,
|
|
344
|
-
fileBlob: undefined,
|
|
345
|
-
status: 'success',
|
|
346
|
-
response: response.success,
|
|
347
|
-
};
|
|
348
|
-
}
|
|
349
|
-
if (onEventCallback) {
|
|
350
|
-
onEventCallback({
|
|
351
|
-
callback_type: CALLBACK_TYPE.FILE_UPLOAD_STATUS,
|
|
352
|
-
status: 'success',
|
|
353
|
-
message: response.success,
|
|
354
|
-
timestamp: new Date().toISOString(),
|
|
355
|
-
data: {
|
|
356
|
-
success: this.successfulUploads.length,
|
|
357
|
-
total: this.audioChunks.length,
|
|
358
|
-
is_uploaded: true,
|
|
359
|
-
},
|
|
360
|
-
});
|
|
361
|
-
}
|
|
314
|
+
const onEventCallback = store_1.default.eventCallback;
|
|
315
|
+
if (onEventCallback) {
|
|
316
|
+
onEventCallback({
|
|
317
|
+
callback_type: enums_1.CALLBACK_TYPE.FILE_UPLOAD_STATUS,
|
|
318
|
+
status: 'info',
|
|
319
|
+
message: 'Audio chunks count to display success/total file count and to store chunks in IDB',
|
|
320
|
+
timestamp: new Date().toISOString(),
|
|
321
|
+
data: {
|
|
322
|
+
success: this.successfulUploads.length,
|
|
323
|
+
total: this.audioChunks.length,
|
|
324
|
+
fileName,
|
|
325
|
+
chunkData: compressedAudioBuffer,
|
|
326
|
+
},
|
|
327
|
+
});
|
|
362
328
|
}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
329
|
+
const s3BucketName = (0, helper_1.GET_S3_BUCKET_NAME)();
|
|
330
|
+
// Push upload promise to track status
|
|
331
|
+
const uploadPromise = (0, upload_file_to_s3_1.default)({
|
|
332
|
+
s3BucketName,
|
|
333
|
+
fileBlob: audioBlob,
|
|
334
|
+
fileName: s3FileName,
|
|
335
|
+
txnID: this.txnID,
|
|
336
|
+
businessID: this.businessID,
|
|
337
|
+
is_shared_worker: false,
|
|
338
|
+
}).then((response) => {
|
|
339
|
+
// callback
|
|
340
|
+
if (response.success) {
|
|
341
|
+
this.successfulUploads.push(fileName);
|
|
342
|
+
// update file status if file uploaded successfully
|
|
343
|
+
if (chunkIndex !== -1) {
|
|
344
|
+
this.audioChunks[chunkIndex] = Object.assign(Object.assign({}, this.audioChunks[chunkIndex]), { audioFrames: undefined, fileBlob: undefined, status: 'success', response: response.success });
|
|
345
|
+
}
|
|
346
|
+
if (onEventCallback) {
|
|
347
|
+
onEventCallback({
|
|
348
|
+
callback_type: enums_1.CALLBACK_TYPE.FILE_UPLOAD_STATUS,
|
|
349
|
+
status: 'success',
|
|
350
|
+
message: response.success,
|
|
351
|
+
timestamp: new Date().toISOString(),
|
|
352
|
+
data: {
|
|
353
|
+
success: this.successfulUploads.length,
|
|
354
|
+
total: this.audioChunks.length,
|
|
355
|
+
is_uploaded: true,
|
|
356
|
+
},
|
|
357
|
+
});
|
|
358
|
+
}
|
|
372
359
|
}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
360
|
+
else {
|
|
361
|
+
if (chunkIndex !== -1) {
|
|
362
|
+
this.audioChunks[chunkIndex] = Object.assign(Object.assign({}, this.audioChunks[chunkIndex]), { fileBlob: audioBlob, audioFrames: undefined, status: 'failure', response: response.error || 'Upload failed' });
|
|
363
|
+
}
|
|
364
|
+
if (onEventCallback) {
|
|
365
|
+
onEventCallback({
|
|
366
|
+
callback_type: enums_1.CALLBACK_TYPE.FILE_UPLOAD_STATUS,
|
|
367
|
+
status: 'error',
|
|
368
|
+
message: response.error || 'Upload failed',
|
|
369
|
+
timestamp: new Date().toISOString(),
|
|
370
|
+
error: {
|
|
371
|
+
code: response.code || 500,
|
|
372
|
+
msg: response.error || 'Upload failed',
|
|
373
|
+
details: response.errorCode,
|
|
374
|
+
},
|
|
375
|
+
data: {
|
|
376
|
+
fileName,
|
|
377
|
+
is_uploaded: false,
|
|
378
|
+
},
|
|
379
|
+
});
|
|
380
|
+
}
|
|
389
381
|
}
|
|
390
|
-
|
|
391
|
-
|
|
382
|
+
return response;
|
|
383
|
+
});
|
|
384
|
+
this.uploadPromises.push(uploadPromise);
|
|
385
|
+
return {
|
|
386
|
+
success: true,
|
|
387
|
+
fileName,
|
|
388
|
+
};
|
|
392
389
|
});
|
|
393
|
-
this.uploadPromises.push(uploadPromise);
|
|
394
|
-
return {
|
|
395
|
-
success: true,
|
|
396
|
-
fileName,
|
|
397
|
-
};
|
|
398
390
|
}
|
|
399
391
|
/**
|
|
400
392
|
* Upload audio chunks to S3 in shared worker
|
|
401
393
|
*/
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
onEventCallback
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
394
|
+
uploadAudioChunkInWorker(_a) {
|
|
395
|
+
return __awaiter(this, arguments, void 0, function* ({ audioFrames, fileName, chunkIndex, }) {
|
|
396
|
+
var _b;
|
|
397
|
+
const s3FileName = `${this.filePath}/${fileName}`;
|
|
398
|
+
const onEventCallback = store_1.default.eventCallback;
|
|
399
|
+
if (onEventCallback) {
|
|
400
|
+
onEventCallback({
|
|
401
|
+
callback_type: enums_1.CALLBACK_TYPE.FILE_UPLOAD_STATUS,
|
|
402
|
+
status: 'info',
|
|
403
|
+
message: 'Audio chunks count to display success/total file count',
|
|
404
|
+
timestamp: new Date().toISOString(),
|
|
405
|
+
data: {
|
|
406
|
+
success: this.successfulUploads.length,
|
|
407
|
+
total: this.audioChunks.length,
|
|
408
|
+
},
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
const s3BucketName = (0, helper_1.GET_S3_BUCKET_NAME)();
|
|
412
|
+
(_b = this.sharedWorkerInstance) === null || _b === void 0 ? void 0 : _b.port.postMessage({
|
|
413
|
+
action: enums_1.SHARED_WORKER_ACTION.UPLOAD_FILE_WITH_WORKER,
|
|
414
|
+
payload: {
|
|
415
|
+
s3BucketName,
|
|
416
|
+
audioFrames,
|
|
417
|
+
fileName: s3FileName,
|
|
418
|
+
txnID: this.txnID,
|
|
419
|
+
businessID: this.businessID,
|
|
420
|
+
chunkIndex,
|
|
421
|
+
fileCount: fileName,
|
|
414
422
|
},
|
|
415
423
|
});
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
payload: {
|
|
421
|
-
s3BucketName,
|
|
422
|
-
audioFrames,
|
|
423
|
-
fileName: s3FileName,
|
|
424
|
-
txnID: this.txnID,
|
|
425
|
-
businessID: this.businessID,
|
|
426
|
-
chunkIndex,
|
|
427
|
-
fileCount: fileName,
|
|
428
|
-
},
|
|
424
|
+
return {
|
|
425
|
+
success: true,
|
|
426
|
+
fileName,
|
|
427
|
+
};
|
|
429
428
|
});
|
|
430
|
-
return {
|
|
431
|
-
success: true,
|
|
432
|
-
fileName,
|
|
433
|
-
};
|
|
434
429
|
}
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
430
|
+
uploadAudioToS3(_a) {
|
|
431
|
+
return __awaiter(this, arguments, void 0, function* ({ audioFrames, fileName, chunkIndex }) {
|
|
432
|
+
if (typeof SharedWorker === 'undefined' || !SharedWorker) {
|
|
433
|
+
// Shared Workers are not supported in this browser
|
|
434
|
+
console.log('Shared Workers are NOT supported in this browser.');
|
|
435
|
+
yield this.uploadAudioToS3WithoutWorker({ audioFrames, fileName, chunkIndex });
|
|
436
|
+
}
|
|
437
|
+
else {
|
|
438
|
+
// Shared Workers are supported
|
|
439
|
+
console.log('Shared Workers are supported in this browser.');
|
|
440
|
+
if (!this.sharedWorkerInstance) {
|
|
441
|
+
const workerCreated = this.createSharedWorkerInstance();
|
|
442
|
+
if (!workerCreated) {
|
|
443
|
+
// SharedWorker creation failed (likely due to CORS/same-origin policy)
|
|
444
|
+
// Fall back to non-worker upload
|
|
445
|
+
console.warn('Failed to create SharedWorker instance. Falling back to non-worker upload method.');
|
|
446
|
+
yield this.uploadAudioToS3WithoutWorker({ audioFrames, fileName, chunkIndex });
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
452
449
|
}
|
|
450
|
+
yield this.uploadAudioToS3WithWorker({ audioFrames, fileName, chunkIndex });
|
|
453
451
|
}
|
|
454
|
-
|
|
455
|
-
}
|
|
452
|
+
});
|
|
456
453
|
}
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
454
|
+
uploadAudioToS3WithWorker(_a) {
|
|
455
|
+
return __awaiter(this, arguments, void 0, function* ({ audioFrames, fileName, chunkIndex, }) {
|
|
456
|
+
try {
|
|
457
|
+
if (!this.isAWSConfigured) {
|
|
458
|
+
const awsConfigResponse = yield this.setupAWSConfiguration({
|
|
459
|
+
is_shared_worker: true,
|
|
460
|
+
});
|
|
461
|
+
if (!awsConfigResponse) {
|
|
462
|
+
throw new Error('Failed to configure AWS');
|
|
463
|
+
}
|
|
465
464
|
}
|
|
465
|
+
yield this.uploadAudioChunkInWorker({ audioFrames, fileName, chunkIndex });
|
|
466
466
|
}
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
}
|
|
467
|
+
catch (error) {
|
|
468
|
+
console.error('Error uploading audio to S3: uploadAudioToS3WithWorker: ', error);
|
|
469
|
+
// Fall back to non-worker upload if worker fails
|
|
470
|
+
yield this.uploadAudioToS3WithoutWorker({ audioFrames, fileName, chunkIndex });
|
|
471
|
+
}
|
|
472
|
+
});
|
|
474
473
|
}
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
474
|
+
uploadAudioToS3WithoutWorker(_a) {
|
|
475
|
+
return __awaiter(this, arguments, void 0, function* ({ audioFrames, fileName, chunkIndex, }) {
|
|
476
|
+
try {
|
|
477
|
+
if (!this.isAWSConfigured) {
|
|
478
|
+
const awsConfigResponse = yield this.setupAWSConfiguration({
|
|
479
|
+
is_shared_worker: false,
|
|
480
|
+
});
|
|
481
|
+
if (!awsConfigResponse) {
|
|
482
|
+
throw new Error('Failed to configure AWS');
|
|
483
|
+
}
|
|
483
484
|
}
|
|
485
|
+
yield this.uploadAudioChunkInMain({ audioFrames, fileName, chunkIndex });
|
|
484
486
|
}
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
}
|
|
487
|
+
catch (error) {
|
|
488
|
+
console.error('Error uploading audio to S3:', error);
|
|
489
|
+
}
|
|
490
|
+
});
|
|
490
491
|
}
|
|
491
492
|
/**
|
|
492
493
|
* Download audio as a file to the user's device (for debugging)
|
|
@@ -505,36 +506,41 @@ class AudioFileManager {
|
|
|
505
506
|
/**
|
|
506
507
|
* Wait for all upload promises to complete
|
|
507
508
|
*/
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
if (uploadRequestReceived === 0) {
|
|
520
|
-
this.sharedWorkerInstance?.port.removeEventListener('message', messageHandler);
|
|
521
|
-
reject();
|
|
509
|
+
waitForAllUploads() {
|
|
510
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
511
|
+
if (this.sharedWorkerInstance) {
|
|
512
|
+
return new Promise((resolve, reject) => {
|
|
513
|
+
var _a, _b;
|
|
514
|
+
// one-time message handler to listen for the response
|
|
515
|
+
const messageHandler = (event) => {
|
|
516
|
+
var _a, _b, _c;
|
|
517
|
+
if (event.data.action === enums_1.SHARED_WORKER_ACTION.WAIT_FOR_ALL_UPLOADS_SUCCESS) {
|
|
518
|
+
(_a = this.sharedWorkerInstance) === null || _a === void 0 ? void 0 : _a.port.removeEventListener('message', messageHandler);
|
|
519
|
+
resolve();
|
|
522
520
|
}
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
521
|
+
else if (event.data.action === enums_1.SHARED_WORKER_ACTION.WAIT_FOR_ALL_UPLOADS_ERROR) {
|
|
522
|
+
const { uploadRequestReceived } = event.data.response || {};
|
|
523
|
+
if (uploadRequestReceived === 0) {
|
|
524
|
+
(_b = this.sharedWorkerInstance) === null || _b === void 0 ? void 0 : _b.port.removeEventListener('message', messageHandler);
|
|
525
|
+
reject();
|
|
526
|
+
}
|
|
527
|
+
(_c = this.sharedWorkerInstance) === null || _c === void 0 ? void 0 : _c.port.postMessage({
|
|
528
|
+
action: enums_1.SHARED_WORKER_ACTION.WAIT_FOR_ALL_UPLOADS,
|
|
529
|
+
});
|
|
530
|
+
}
|
|
531
|
+
};
|
|
532
|
+
// one-time listener
|
|
533
|
+
(_a = this.sharedWorkerInstance) === null || _a === void 0 ? void 0 : _a.port.addEventListener('message', messageHandler);
|
|
534
|
+
(_b = this.sharedWorkerInstance) === null || _b === void 0 ? void 0 : _b.port.postMessage({
|
|
535
|
+
action: enums_1.SHARED_WORKER_ACTION.WAIT_FOR_ALL_UPLOADS,
|
|
536
|
+
});
|
|
532
537
|
});
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
+
}
|
|
539
|
+
else {
|
|
540
|
+
// ES2015-compatible alternative to Promise.allSettled
|
|
541
|
+
yield Promise.all(this.uploadPromises.map((promise) => promise.catch((error) => ({ error: String(error) }))));
|
|
542
|
+
}
|
|
543
|
+
});
|
|
538
544
|
}
|
|
539
545
|
/**
|
|
540
546
|
* Get list of successfully uploaded files
|
|
@@ -563,104 +569,101 @@ class AudioFileManager {
|
|
|
563
569
|
/**
|
|
564
570
|
* Retry uploading failed files
|
|
565
571
|
*/
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
const onEventCallback = EkaScribeStore.eventCallback;
|
|
572
|
-
const s3BucketName = GET_S3_BUCKET_NAME();
|
|
573
|
-
if (this.sharedWorkerInstance) {
|
|
574
|
-
this.audioChunks.forEach((chunk, index) => {
|
|
575
|
-
const { fileName, fileBlob, status, audioFrames } = chunk;
|
|
576
|
-
if (status != 'success') {
|
|
577
|
-
// callback
|
|
578
|
-
this.sharedWorkerInstance?.port.postMessage({
|
|
579
|
-
action: SHARED_WORKER_ACTION.UPLOAD_FILE_WITH_WORKER,
|
|
580
|
-
payload: {
|
|
581
|
-
s3BucketName,
|
|
582
|
-
audioFrames,
|
|
583
|
-
fileBlob,
|
|
584
|
-
fileName: `${this.filePath}/${fileName}`,
|
|
585
|
-
txnID: this.txnID,
|
|
586
|
-
businessID: this.businessID,
|
|
587
|
-
chunkIndex: index,
|
|
588
|
-
fileCount: fileName,
|
|
589
|
-
},
|
|
590
|
-
});
|
|
591
|
-
}
|
|
592
|
-
});
|
|
593
|
-
}
|
|
594
|
-
else {
|
|
595
|
-
this.uploadPromises = []; // Reset upload promises for retries
|
|
596
|
-
if (onEventCallback) {
|
|
597
|
-
onEventCallback({
|
|
598
|
-
callback_type: CALLBACK_TYPE.FILE_UPLOAD_STATUS,
|
|
599
|
-
status: 'info',
|
|
600
|
-
message: 'Audio chunks count to display success/total file count',
|
|
601
|
-
timestamp: new Date().toISOString(),
|
|
602
|
-
data: {
|
|
603
|
-
success: this.successfulUploads.length,
|
|
604
|
-
total: this.audioChunks.length,
|
|
605
|
-
},
|
|
606
|
-
});
|
|
572
|
+
retryFailedUploads() {
|
|
573
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
574
|
+
const failedFiles = this.getFailedUploads();
|
|
575
|
+
if (failedFiles.length === 0) {
|
|
576
|
+
return [];
|
|
607
577
|
}
|
|
608
|
-
const
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
if (status
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
578
|
+
const onEventCallback = store_1.default.eventCallback;
|
|
579
|
+
const s3BucketName = (0, helper_1.GET_S3_BUCKET_NAME)();
|
|
580
|
+
if (this.sharedWorkerInstance) {
|
|
581
|
+
this.audioChunks.forEach((chunk, index) => {
|
|
582
|
+
var _a;
|
|
583
|
+
const { fileName, fileBlob, status, audioFrames } = chunk;
|
|
584
|
+
if (status != 'success') {
|
|
585
|
+
// callback
|
|
586
|
+
(_a = this.sharedWorkerInstance) === null || _a === void 0 ? void 0 : _a.port.postMessage({
|
|
587
|
+
action: enums_1.SHARED_WORKER_ACTION.UPLOAD_FILE_WITH_WORKER,
|
|
588
|
+
payload: {
|
|
589
|
+
s3BucketName,
|
|
590
|
+
audioFrames,
|
|
591
|
+
fileBlob,
|
|
592
|
+
fileName: `${this.filePath}/${fileName}`,
|
|
593
|
+
txnID: this.txnID,
|
|
594
|
+
businessID: this.businessID,
|
|
595
|
+
chunkIndex: index,
|
|
596
|
+
fileCount: fileName,
|
|
597
|
+
},
|
|
621
598
|
});
|
|
622
599
|
}
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
else {
|
|
603
|
+
this.uploadPromises = []; // Reset upload promises for retries
|
|
604
|
+
if (onEventCallback) {
|
|
605
|
+
onEventCallback({
|
|
606
|
+
callback_type: enums_1.CALLBACK_TYPE.FILE_UPLOAD_STATUS,
|
|
607
|
+
status: 'info',
|
|
608
|
+
message: 'Audio chunks count to display success/total file count',
|
|
609
|
+
timestamp: new Date().toISOString(),
|
|
610
|
+
data: {
|
|
611
|
+
success: this.successfulUploads.length,
|
|
612
|
+
total: this.audioChunks.length,
|
|
613
|
+
},
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
const s3BucketName = (0, helper_1.GET_S3_BUCKET_NAME)();
|
|
617
|
+
this.audioChunks.forEach((chunk, index) => {
|
|
618
|
+
const { fileName, fileBlob, status, audioFrames } = chunk;
|
|
619
|
+
if (status != 'success') {
|
|
620
|
+
// callback
|
|
621
|
+
let failedFileBlob;
|
|
622
|
+
if (status === 'failure') {
|
|
623
|
+
failedFileBlob = fileBlob;
|
|
624
|
+
}
|
|
625
|
+
if (status === 'pending') {
|
|
626
|
+
const compressedAudioBuffer = (0, compress_mp3_audio_1.default)(audioFrames);
|
|
627
|
+
failedFileBlob = new Blob(compressedAudioBuffer, {
|
|
628
|
+
type: constant_1.AUDIO_EXTENSION_TYPE_MAP[constant_1.OUTPUT_FORMAT],
|
|
629
|
+
});
|
|
630
|
+
}
|
|
631
|
+
if (failedFileBlob) {
|
|
632
|
+
const uploadPromise = (0, upload_file_to_s3_1.default)({
|
|
633
|
+
s3BucketName,
|
|
634
|
+
fileBlob: failedFileBlob,
|
|
635
|
+
fileName: `${this.filePath}/${fileName}`,
|
|
636
|
+
txnID: this.txnID,
|
|
637
|
+
businessID: this.businessID,
|
|
638
|
+
is_shared_worker: false,
|
|
639
|
+
}).then((response) => {
|
|
640
|
+
if (response.success) {
|
|
641
|
+
this.successfulUploads.push(fileName);
|
|
642
|
+
if (onEventCallback) {
|
|
643
|
+
onEventCallback({
|
|
644
|
+
callback_type: enums_1.CALLBACK_TYPE.FILE_UPLOAD_STATUS,
|
|
645
|
+
status: 'info',
|
|
646
|
+
message: 'Audio chunks count to display success/total file count',
|
|
647
|
+
timestamp: new Date().toISOString(),
|
|
648
|
+
data: {
|
|
649
|
+
success: this.successfulUploads.length,
|
|
650
|
+
total: this.audioChunks.length,
|
|
651
|
+
},
|
|
652
|
+
});
|
|
653
|
+
}
|
|
654
|
+
this.audioChunks[index] = Object.assign(Object.assign({}, this.audioChunks[index]), { audioFrames: undefined, fileBlob: undefined, status: 'success', response: response.success });
|
|
645
655
|
}
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
status: 'success',
|
|
651
|
-
response: response.success,
|
|
652
|
-
};
|
|
653
|
-
}
|
|
654
|
-
return response;
|
|
655
|
-
});
|
|
656
|
-
this.uploadPromises.push(uploadPromise);
|
|
656
|
+
return response;
|
|
657
|
+
});
|
|
658
|
+
this.uploadPromises.push(uploadPromise);
|
|
659
|
+
}
|
|
657
660
|
}
|
|
658
|
-
}
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
661
|
+
});
|
|
662
|
+
}
|
|
663
|
+
// Wait for all retry promises to complete
|
|
664
|
+
yield this.waitForAllUploads();
|
|
665
|
+
return this.getFailedUploads();
|
|
666
|
+
});
|
|
664
667
|
}
|
|
665
668
|
/**
|
|
666
669
|
* Reset the upload state
|
|
@@ -685,4 +688,4 @@ class AudioFileManager {
|
|
|
685
688
|
this.isAWSConfigured = false;
|
|
686
689
|
}
|
|
687
690
|
}
|
|
688
|
-
|
|
691
|
+
exports.default = AudioFileManager;
|