@eka-care/ekascribe-ts-sdk 2.0.62 → 2.1.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.
package/dist/index.mjs CHANGED
@@ -11218,7 +11218,7 @@ class EkaScribeStore {
11218
11218
  }
11219
11219
  }
11220
11220
  const EkaScribeStore$1 = EkaScribeStore.getInstance();
11221
- var ERROR_CODE = /* @__PURE__ */ ((i) => (i.MICROPHONE = "microphone", i.TXN_INIT_FAILED = "txn_init_failed", i.TXN_LIMIT_EXCEEDED = "txn_limit_exceeded", i.INTERNAL_SERVER_ERROR = "internal_server_error", i.TXN_STOP_FAILED = "txn_stop_failed", i.AUDIO_UPLOAD_FAILED = "audio_upload_failed", i.TXN_COMMIT_FAILED = "txn_commit_failed", i.INVALID_REQUEST = "invalid_request", i.VAD_NOT_INITIALIZED = "vad_not_initialized", i.NO_AUDIO_CAPTURE = "no_audio_capture", i.SPEECH_DETECTED = "speech_detected", i.TXN_STATUS_MISMATCH = "txn_status_mismatch", i.LONG_SILENCE = "long_silence", i.GET_PRESIGNED_URL_FAILED = "get_presigned_url_failed", i.UPLOAD_FULL_AUDIO = "upload_full_audio", i.FETCH_WRAPPER_RESPONSE = "fetch_wrapper_response", i.FETCH_WRAPPER_ERROR = "fetch_wrapper_error", i))(ERROR_CODE || {}), SHARED_WORKER_ACTION = /* @__PURE__ */ ((i) => (i.UPLOAD_FILE_WITH_WORKER = "upload_file_with_worker", i.UPLOAD_FILE_WITH_WORKER_SUCCESS = "upload_file_with_worker_success", i.UPLOAD_FILE_WITH_WORKER_ERROR = "upload_file_with_worker_error", i.TEST_WORKER = "test_worker", i.CONFIGURE_AWS = "configure_aws", i.CONFIGURE_AWS_SUCCESS = "configure_aws_success", i.CONFIGURE_AWS_ERROR = "configure_aws_error", i.WAIT_FOR_ALL_UPLOADS = "wait_for_all_uploads", i.WAIT_FOR_ALL_UPLOADS_SUCCESS = "wait_for_all_uploads_success", i.WAIT_FOR_ALL_UPLOADS_ERROR = "wait_for_all_uploads_error", i))(SHARED_WORKER_ACTION || {}), CALLBACK_TYPE = /* @__PURE__ */ ((i) => (i.AWS_CONFIGURE_STATUS = "aws_configure_status", i.FILE_UPLOAD_STATUS = "file_upload_status", i.TRANSACTION_STATUS = "transaction_status", i.TEMPLATE_OPERATION_STATUS = "template_operation_status", i.AUTHENTICATION_STATUS = "authentication_status", i.NETWORK_STATUS = "network_status", i.STORAGE_STATUS = "storage_status", i))(CALLBACK_TYPE || {}), TEMPLATE_TYPE = /* @__PURE__ */ ((i) => (i.JSON = "json", i.TRANSCRIPT = "transcript", i.MARKDOWN = "markdown", i))(TEMPLATE_TYPE || {}), COMPATIBILITY_TEST_TYPE = /* @__PURE__ */ ((i) => (i.INTERNET_CONNECTIVITY = "INTERNET_CONNECTIVITY", i.SYSTEM_INFO = "SYSTEM_INFO", i.MICROPHONE = "MICROPHONE", i.SHARED_WORKER = "SHARED_WORKER", i.NETWORK_API = "NETWORK_API", i))(COMPATIBILITY_TEST_TYPE || {}), COMPATIBILITY_TEST_STATUS = /* @__PURE__ */ ((i) => (i.SUCCESS = "success", i.ERROR = "error", i.WARNING = "warning", i))(COMPATIBILITY_TEST_STATUS || {});
11221
+ var ERROR_CODE = /* @__PURE__ */ ((i) => (i.MICROPHONE = "microphone", i.TXN_INIT_FAILED = "txn_init_failed", i.TXN_LIMIT_EXCEEDED = "txn_limit_exceeded", i.INTERNAL_SERVER_ERROR = "internal_server_error", i.TXN_STOP_FAILED = "txn_stop_failed", i.AUDIO_UPLOAD_FAILED = "audio_upload_failed", i.TXN_COMMIT_FAILED = "txn_commit_failed", i.INVALID_REQUEST = "invalid_request", i.VAD_NOT_INITIALIZED = "vad_not_initialized", i.NO_AUDIO_CAPTURE = "no_audio_capture", i.SPEECH_DETECTED = "speech_detected", i.TXN_STATUS_MISMATCH = "txn_status_mismatch", i.LONG_SILENCE = "long_silence", i.GET_PRESIGNED_URL_FAILED = "get_presigned_url_failed", i.UPLOAD_FULL_AUDIO = "upload_full_audio", i.FETCH_WRAPPER_RESPONSE = "fetch_wrapper_response", i.FETCH_WRAPPER_ERROR = "fetch_wrapper_error", i))(ERROR_CODE || {}), SHARED_WORKER_ACTION = /* @__PURE__ */ ((i) => (i.UPLOAD_FILE_WITH_WORKER = "upload_file_with_worker", i.UPLOAD_FILE_WITH_WORKER_SUCCESS = "upload_file_with_worker_success", i.UPLOAD_FILE_WITH_WORKER_ERROR = "upload_file_with_worker_error", i.TEST_WORKER = "test_worker", i.CONFIGURE_AWS = "configure_aws", i.CONFIGURE_AWS_SUCCESS = "configure_aws_success", i.CONFIGURE_AWS_ERROR = "configure_aws_error", i.WAIT_FOR_ALL_UPLOADS = "wait_for_all_uploads", i.WAIT_FOR_ALL_UPLOADS_SUCCESS = "wait_for_all_uploads_success", i.WAIT_FOR_ALL_UPLOADS_ERROR = "wait_for_all_uploads_error", i.REQUEST_TOKEN_REFRESH = "request_token_refresh", i.TOKEN_REFRESH_SUCCESS = "token_refresh_success", i.TOKEN_REFRESH_ERROR = "token_refresh_error", i))(SHARED_WORKER_ACTION || {}), CALLBACK_TYPE = /* @__PURE__ */ ((i) => (i.AWS_CONFIGURE_STATUS = "aws_configure_status", i.FILE_UPLOAD_STATUS = "file_upload_status", i.TRANSACTION_STATUS = "transaction_status", i.TEMPLATE_OPERATION_STATUS = "template_operation_status", i.AUTHENTICATION_STATUS = "authentication_status", i.NETWORK_STATUS = "network_status", i.STORAGE_STATUS = "storage_status", i))(CALLBACK_TYPE || {}), TEMPLATE_TYPE = /* @__PURE__ */ ((i) => (i.JSON = "json", i.TRANSCRIPT = "transcript", i.MARKDOWN = "markdown", i))(TEMPLATE_TYPE || {}), COMPATIBILITY_TEST_TYPE = /* @__PURE__ */ ((i) => (i.INTERNET_CONNECTIVITY = "INTERNET_CONNECTIVITY", i.SYSTEM_INFO = "SYSTEM_INFO", i.MICROPHONE = "MICROPHONE", i.SHARED_WORKER = "SHARED_WORKER", i.NETWORK_API = "NETWORK_API", i))(COMPATIBILITY_TEST_TYPE || {}), COMPATIBILITY_TEST_STATUS = /* @__PURE__ */ ((i) => (i.SUCCESS = "success", i.ERROR = "error", i.WARNING = "warning", i))(COMPATIBILITY_TEST_STATUS || {});
11222
11222
  const API_TIMEOUT_MS = 1e4;
11223
11223
  async function fetchWrapper(i, a = {}, s = API_TIMEOUT_MS) {
11224
11224
  const n = EkaScribeStore$1.eventCallback, r = new AbortController();
@@ -11496,6 +11496,198 @@ async function postCogInit() {
11496
11496
  throw i;
11497
11497
  }
11498
11498
  }
11499
+ const encoder = new TextEncoder(), HOST_SERVICES = {
11500
+ appstream2: "appstream",
11501
+ cloudhsmv2: "cloudhsm",
11502
+ email: "ses",
11503
+ marketplace: "aws-marketplace",
11504
+ mobile: "AWSMobileHubService",
11505
+ pinpoint: "mobiletargeting",
11506
+ queue: "sqs",
11507
+ "git-codecommit": "codecommit",
11508
+ "mturk-requester-sandbox": "mturk-requester",
11509
+ "personalize-runtime": "personalize"
11510
+ }, UNSIGNABLE_HEADERS = /* @__PURE__ */ new Set([
11511
+ "authorization",
11512
+ "content-type",
11513
+ "content-length",
11514
+ "user-agent",
11515
+ "presigned-expires",
11516
+ "expect",
11517
+ "x-amzn-trace-id",
11518
+ "range",
11519
+ "connection"
11520
+ ]);
11521
+ class AwsClient {
11522
+ constructor({ accessKeyId: a, secretAccessKey: s, sessionToken: n, service: r, region: c, cache: u, retries: m, initRetryMs: y }) {
11523
+ if (a == null) throw new TypeError("accessKeyId is a required option");
11524
+ if (s == null) throw new TypeError("secretAccessKey is a required option");
11525
+ this.accessKeyId = a, this.secretAccessKey = s, this.sessionToken = n, this.service = r, this.region = c, this.cache = u || /* @__PURE__ */ new Map(), this.retries = m ?? 10, this.initRetryMs = y || 50;
11526
+ }
11527
+ async sign(a, s) {
11528
+ if (a instanceof Request) {
11529
+ const { method: c, url: u, headers: m, body: y } = a;
11530
+ s = Object.assign({ method: c, url: u, headers: m }, s), s.body == null && m.has("Content-Type") && (s.body = y != null && m.has("X-Amz-Content-Sha256") ? y : await a.clone().arrayBuffer()), a = u;
11531
+ }
11532
+ const n = new AwsV4Signer(Object.assign({ url: a.toString() }, s, this, s && s.aws)), r = Object.assign({}, s, await n.sign());
11533
+ delete r.aws;
11534
+ try {
11535
+ return new Request(r.url.toString(), r);
11536
+ } catch (c) {
11537
+ if (c instanceof TypeError)
11538
+ return new Request(r.url.toString(), Object.assign({ duplex: "half" }, r));
11539
+ throw c;
11540
+ }
11541
+ }
11542
+ async fetch(a, s) {
11543
+ for (let n = 0; n <= this.retries; n++) {
11544
+ const r = fetch(await this.sign(a, s));
11545
+ if (n === this.retries)
11546
+ return r;
11547
+ const c = await r;
11548
+ if (c.status < 500 && c.status !== 429)
11549
+ return c;
11550
+ await new Promise((u) => setTimeout(u, Math.random() * this.initRetryMs * Math.pow(2, n)));
11551
+ }
11552
+ throw new Error("An unknown error occurred, ensure retries is not negative");
11553
+ }
11554
+ }
11555
+ class AwsV4Signer {
11556
+ constructor({ method: a, url: s, headers: n, body: r, accessKeyId: c, secretAccessKey: u, sessionToken: m, service: y, region: l, cache: p, datetime: t, signQuery: e, appendSessionToken: o, allHeaders: d, singleEncode: h }) {
11557
+ if (s == null) throw new TypeError("url is a required option");
11558
+ if (c == null) throw new TypeError("accessKeyId is a required option");
11559
+ if (u == null) throw new TypeError("secretAccessKey is a required option");
11560
+ this.method = a || (r ? "POST" : "GET"), this.url = new URL(s), this.headers = new Headers(n || {}), this.body = r, this.accessKeyId = c, this.secretAccessKey = u, this.sessionToken = m;
11561
+ let g, b;
11562
+ (!y || !l) && ([g, b] = guessServiceRegion(this.url, this.headers)), this.service = y || g || "", this.region = l || b || "us-east-1", this.cache = p || /* @__PURE__ */ new Map(), this.datetime = t || (/* @__PURE__ */ new Date()).toISOString().replace(/[:-]|\.\d{3}/g, ""), this.signQuery = e, this.appendSessionToken = o || this.service === "iotdevicegateway", this.headers.delete("Host"), this.service === "s3" && !this.signQuery && !this.headers.has("X-Amz-Content-Sha256") && this.headers.set("X-Amz-Content-Sha256", "UNSIGNED-PAYLOAD");
11563
+ const f = this.signQuery ? this.url.searchParams : this.headers;
11564
+ if (f.set("X-Amz-Date", this.datetime), this.sessionToken && !this.appendSessionToken && f.set("X-Amz-Security-Token", this.sessionToken), this.signableHeaders = ["host", ...this.headers.keys()].filter((I) => d || !UNSIGNABLE_HEADERS.has(I)).sort(), this.signedHeaders = this.signableHeaders.join(";"), this.canonicalHeaders = this.signableHeaders.map((I) => I + ":" + (I === "host" ? this.url.host : (this.headers.get(I) || "").replace(/\s+/g, " "))).join(`
11565
+ `), this.credentialString = [this.datetime.slice(0, 8), this.region, this.service, "aws4_request"].join("/"), this.signQuery && (this.service === "s3" && !f.has("X-Amz-Expires") && f.set("X-Amz-Expires", "86400"), f.set("X-Amz-Algorithm", "AWS4-HMAC-SHA256"), f.set("X-Amz-Credential", this.accessKeyId + "/" + this.credentialString), f.set("X-Amz-SignedHeaders", this.signedHeaders)), this.service === "s3")
11566
+ try {
11567
+ this.encodedPath = decodeURIComponent(this.url.pathname.replace(/\+/g, " "));
11568
+ } catch {
11569
+ this.encodedPath = this.url.pathname;
11570
+ }
11571
+ else
11572
+ this.encodedPath = this.url.pathname.replace(/\/+/g, "/");
11573
+ h || (this.encodedPath = encodeURIComponent(this.encodedPath).replace(/%2F/g, "/")), this.encodedPath = encodeRfc3986(this.encodedPath);
11574
+ const S = /* @__PURE__ */ new Set();
11575
+ this.encodedSearch = [...this.url.searchParams].filter(([I]) => {
11576
+ if (!I) return !1;
11577
+ if (this.service === "s3") {
11578
+ if (S.has(I)) return !1;
11579
+ S.add(I);
11580
+ }
11581
+ return !0;
11582
+ }).map((I) => I.map((v) => encodeRfc3986(encodeURIComponent(v)))).sort(([I, v], [T, R]) => I < T ? -1 : I > T ? 1 : v < R ? -1 : v > R ? 1 : 0).map((I) => I.join("=")).join("&");
11583
+ }
11584
+ async sign() {
11585
+ return this.signQuery ? (this.url.searchParams.set("X-Amz-Signature", await this.signature()), this.sessionToken && this.appendSessionToken && this.url.searchParams.set("X-Amz-Security-Token", this.sessionToken)) : this.headers.set("Authorization", await this.authHeader()), {
11586
+ method: this.method,
11587
+ url: this.url,
11588
+ headers: this.headers,
11589
+ body: this.body
11590
+ };
11591
+ }
11592
+ async authHeader() {
11593
+ return [
11594
+ "AWS4-HMAC-SHA256 Credential=" + this.accessKeyId + "/" + this.credentialString,
11595
+ "SignedHeaders=" + this.signedHeaders,
11596
+ "Signature=" + await this.signature()
11597
+ ].join(", ");
11598
+ }
11599
+ async signature() {
11600
+ const a = this.datetime.slice(0, 8), s = [this.secretAccessKey, a, this.region, this.service].join();
11601
+ let n = this.cache.get(s);
11602
+ if (!n) {
11603
+ const r = await hmac("AWS4" + this.secretAccessKey, a), c = await hmac(r, this.region), u = await hmac(c, this.service);
11604
+ n = await hmac(u, "aws4_request"), this.cache.set(s, n);
11605
+ }
11606
+ return buf2hex(await hmac(n, await this.stringToSign()));
11607
+ }
11608
+ async stringToSign() {
11609
+ return [
11610
+ "AWS4-HMAC-SHA256",
11611
+ this.datetime,
11612
+ this.credentialString,
11613
+ buf2hex(await hash(await this.canonicalString()))
11614
+ ].join(`
11615
+ `);
11616
+ }
11617
+ async canonicalString() {
11618
+ return [
11619
+ this.method.toUpperCase(),
11620
+ this.encodedPath,
11621
+ this.encodedSearch,
11622
+ this.canonicalHeaders + `
11623
+ `,
11624
+ this.signedHeaders,
11625
+ await this.hexBodyHash()
11626
+ ].join(`
11627
+ `);
11628
+ }
11629
+ async hexBodyHash() {
11630
+ let a = this.headers.get("X-Amz-Content-Sha256") || (this.service === "s3" && this.signQuery ? "UNSIGNED-PAYLOAD" : null);
11631
+ if (a == null) {
11632
+ if (this.body && typeof this.body != "string" && !("byteLength" in this.body))
11633
+ throw new Error("body must be a string, ArrayBuffer or ArrayBufferView, unless you include the X-Amz-Content-Sha256 header");
11634
+ a = buf2hex(await hash(this.body || ""));
11635
+ }
11636
+ return a;
11637
+ }
11638
+ }
11639
+ async function hmac(i, a) {
11640
+ const s = await crypto.subtle.importKey(
11641
+ "raw",
11642
+ typeof i == "string" ? encoder.encode(i) : i,
11643
+ { name: "HMAC", hash: { name: "SHA-256" } },
11644
+ !1,
11645
+ ["sign"]
11646
+ );
11647
+ return crypto.subtle.sign("HMAC", s, encoder.encode(a));
11648
+ }
11649
+ async function hash(i) {
11650
+ return crypto.subtle.digest("SHA-256", typeof i == "string" ? encoder.encode(i) : i);
11651
+ }
11652
+ const HEX_CHARS = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"];
11653
+ function buf2hex(i) {
11654
+ const a = new Uint8Array(i);
11655
+ let s = "";
11656
+ for (let n = 0; n < a.length; n++) {
11657
+ const r = a[n];
11658
+ s += HEX_CHARS[r >>> 4 & 15], s += HEX_CHARS[r & 15];
11659
+ }
11660
+ return s;
11661
+ }
11662
+ function encodeRfc3986(i) {
11663
+ return i.replace(/[!'()*]/g, (a) => "%" + a.charCodeAt(0).toString(16).toUpperCase());
11664
+ }
11665
+ function guessServiceRegion(i, a) {
11666
+ const { hostname: s, pathname: n } = i;
11667
+ if (s.endsWith(".on.aws")) {
11668
+ const m = s.match(/^[^.]{1,63}\.lambda-url\.([^.]{1,63})\.on\.aws$/);
11669
+ return m != null ? ["lambda", m[1] || ""] : ["", ""];
11670
+ }
11671
+ if (s.endsWith(".r2.cloudflarestorage.com"))
11672
+ return ["s3", "auto"];
11673
+ if (s.endsWith(".backblazeb2.com")) {
11674
+ const m = s.match(/^(?:[^.]{1,63}\.)?s3\.([^.]{1,63})\.backblazeb2\.com$/);
11675
+ return m != null ? ["s3", m[1] || ""] : ["", ""];
11676
+ }
11677
+ const r = s.replace("dualstack.", "").match(/([^.]{1,63})\.(?:([^.]{0,63})\.)?amazonaws\.com(?:\.cn)?$/);
11678
+ let c = r && r[1] || "", u = r && r[2];
11679
+ if (u === "us-gov")
11680
+ u = "us-gov-west-1";
11681
+ else if (u === "s3" || u === "s3-accelerate")
11682
+ u = "us-east-1", c = "s3";
11683
+ else if (c === "iot")
11684
+ s.startsWith("iot.") ? c = "execute-api" : s.startsWith("data.jobs.iot.") ? c = "iot-jobs-data" : c = n === "/mqtt" ? "iotdevicegateway" : "iotdata";
11685
+ else if (c === "autoscaling") {
11686
+ const m = (a.get("X-Amz-Target") || "").split(".")[0];
11687
+ m === "AnyScaleFrontendService" ? c = "application-autoscaling" : m === "AnyScaleScalingPlannerFrontendService" && (c = "autoscaling-plans");
11688
+ } else u == null && c.startsWith("s3-") ? (u = c.slice(3).replace(/^fips-|^external-1/, ""), c = "s3") : c.endsWith("-fips") ? c = c.slice(0, -5) : u && /-\d$/.test(c) && !/-\d$/.test(u) && ([c, u] = [u, c]);
11689
+ return [HOST_SERVICES[c] || c, u || ""];
11690
+ }
11499
11691
  var browser = { exports: {} }, builder$1, hasRequiredBuilder$1;
11500
11692
  function requireBuilder$1() {
11501
11693
  if (hasRequiredBuilder$1) return builder$1;
@@ -28551,287 +28743,124 @@ function configureAWS({ accessKeyId: i, secretKey: a, sessionToken: s }) {
28551
28743
  function getConfiguredAwsCredentials() {
28552
28744
  return currentAwsCredentials;
28553
28745
  }
28554
- const encoder = new TextEncoder(), HOST_SERVICES = {
28555
- appstream2: "appstream",
28556
- cloudhsmv2: "cloudhsm",
28557
- email: "ses",
28558
- marketplace: "aws-marketplace",
28559
- mobile: "AWSMobileHubService",
28560
- pinpoint: "mobiletargeting",
28561
- queue: "sqs",
28562
- "git-codecommit": "codecommit",
28563
- "mturk-requester-sandbox": "mturk-requester",
28564
- "personalize-runtime": "personalize"
28565
- }, UNSIGNABLE_HEADERS = /* @__PURE__ */ new Set([
28566
- "authorization",
28567
- "content-type",
28568
- "content-length",
28569
- "user-agent",
28570
- "presigned-expires",
28571
- "expect",
28572
- "x-amzn-trace-id",
28573
- "range",
28574
- "connection"
28575
- ]);
28576
- class AwsClient {
28577
- constructor({ accessKeyId: a, secretAccessKey: s, sessionToken: n, service: r, region: c, cache: u, retries: m, initRetryMs: y }) {
28578
- if (a == null) throw new TypeError("accessKeyId is a required option");
28579
- if (s == null) throw new TypeError("secretAccessKey is a required option");
28580
- this.accessKeyId = a, this.secretAccessKey = s, this.sessionToken = n, this.service = r, this.region = c, this.cache = u || /* @__PURE__ */ new Map(), this.retries = m ?? 10, this.initRetryMs = y || 50;
28581
- }
28582
- async sign(a, s) {
28583
- if (a instanceof Request) {
28584
- const { method: c, url: u, headers: m, body: y } = a;
28585
- s = Object.assign({ method: c, url: u, headers: m }, s), s.body == null && m.has("Content-Type") && (s.body = y != null && m.has("X-Amz-Content-Sha256") ? y : await a.clone().arrayBuffer()), a = u;
28586
- }
28587
- const n = new AwsV4Signer(Object.assign({ url: a.toString() }, s, this, s && s.aws)), r = Object.assign({}, s, await n.sign());
28588
- delete r.aws;
28589
- try {
28590
- return new Request(r.url.toString(), r);
28591
- } catch (c) {
28592
- if (c instanceof TypeError)
28593
- return new Request(r.url.toString(), Object.assign({ duplex: "half" }, r));
28594
- throw c;
28595
- }
28596
- }
28597
- async fetch(a, s) {
28598
- for (let n = 0; n <= this.retries; n++) {
28599
- const r = fetch(await this.sign(a, s));
28600
- if (n === this.retries)
28601
- return r;
28602
- const c = await r;
28603
- if (c.status < 500 && c.status !== 429)
28604
- return c;
28605
- await new Promise((u) => setTimeout(u, Math.random() * this.initRetryMs * Math.pow(2, n)));
28606
- }
28607
- throw new Error("An unknown error occurred, ensure retries is not negative");
28608
- }
28746
+ function classifyError(i) {
28747
+ if (i?.is_session_expired)
28748
+ return { isPermanent: !0, code: 401, message: "Session expired. Please re-login." };
28749
+ const a = i?.statusCode || i?.code;
28750
+ return a === 401 ? { isPermanent: !0, code: 401, message: "Authentication failed. Please re-login." } : a === 403 ? { isPermanent: !0, code: 403, message: "Permission denied." } : a === 404 ? { isPermanent: !0, code: 404, message: "Resource not found." } : {
28751
+ isPermanent: !1,
28752
+ code: a || 500,
28753
+ message: i?.message || "Upload failed. Will retry."
28754
+ };
28609
28755
  }
28610
- class AwsV4Signer {
28611
- constructor({ method: a, url: s, headers: n, body: r, accessKeyId: c, secretAccessKey: u, sessionToken: m, service: y, region: l, cache: p, datetime: t, signQuery: e, appendSessionToken: o, allHeaders: d, singleEncode: h }) {
28612
- if (s == null) throw new TypeError("url is a required option");
28613
- if (c == null) throw new TypeError("accessKeyId is a required option");
28614
- if (u == null) throw new TypeError("secretAccessKey is a required option");
28615
- this.method = a || (r ? "POST" : "GET"), this.url = new URL(s), this.headers = new Headers(n || {}), this.body = r, this.accessKeyId = c, this.secretAccessKey = u, this.sessionToken = m;
28616
- let g, b;
28617
- (!y || !l) && ([g, b] = guessServiceRegion(this.url, this.headers)), this.service = y || g || "", this.region = l || b || "us-east-1", this.cache = p || /* @__PURE__ */ new Map(), this.datetime = t || (/* @__PURE__ */ new Date()).toISOString().replace(/[:-]|\.\d{3}/g, ""), this.signQuery = e, this.appendSessionToken = o || this.service === "iotdevicegateway", this.headers.delete("Host"), this.service === "s3" && !this.signQuery && !this.headers.has("X-Amz-Content-Sha256") && this.headers.set("X-Amz-Content-Sha256", "UNSIGNED-PAYLOAD");
28618
- const f = this.signQuery ? this.url.searchParams : this.headers;
28619
- if (f.set("X-Amz-Date", this.datetime), this.sessionToken && !this.appendSessionToken && f.set("X-Amz-Security-Token", this.sessionToken), this.signableHeaders = ["host", ...this.headers.keys()].filter((I) => d || !UNSIGNABLE_HEADERS.has(I)).sort(), this.signedHeaders = this.signableHeaders.join(";"), this.canonicalHeaders = this.signableHeaders.map((I) => I + ":" + (I === "host" ? this.url.host : (this.headers.get(I) || "").replace(/\s+/g, " "))).join(`
28620
- `), this.credentialString = [this.datetime.slice(0, 8), this.region, this.service, "aws4_request"].join("/"), this.signQuery && (this.service === "s3" && !f.has("X-Amz-Expires") && f.set("X-Amz-Expires", "86400"), f.set("X-Amz-Algorithm", "AWS4-HMAC-SHA256"), f.set("X-Amz-Credential", this.accessKeyId + "/" + this.credentialString), f.set("X-Amz-SignedHeaders", this.signedHeaders)), this.service === "s3")
28621
- try {
28622
- this.encodedPath = decodeURIComponent(this.url.pathname.replace(/\+/g, " "));
28623
- } catch {
28624
- this.encodedPath = this.url.pathname;
28625
- }
28626
- else
28627
- this.encodedPath = this.url.pathname.replace(/\/+/g, "/");
28628
- h || (this.encodedPath = encodeURIComponent(this.encodedPath).replace(/%2F/g, "/")), this.encodedPath = encodeRfc3986(this.encodedPath);
28629
- const S = /* @__PURE__ */ new Set();
28630
- this.encodedSearch = [...this.url.searchParams].filter(([I]) => {
28631
- if (!I) return !1;
28632
- if (this.service === "s3") {
28633
- if (S.has(I)) return !1;
28634
- S.add(I);
28635
- }
28636
- return !0;
28637
- }).map((I) => I.map((v) => encodeRfc3986(encodeURIComponent(v)))).sort(([I, v], [T, R]) => I < T ? -1 : I > T ? 1 : v < R ? -1 : v > R ? 1 : 0).map((I) => I.join("=")).join("&");
28638
- }
28639
- async sign() {
28640
- return this.signQuery ? (this.url.searchParams.set("X-Amz-Signature", await this.signature()), this.sessionToken && this.appendSessionToken && this.url.searchParams.set("X-Amz-Security-Token", this.sessionToken)) : this.headers.set("Authorization", await this.authHeader()), {
28641
- method: this.method,
28642
- url: this.url,
28643
- headers: this.headers,
28644
- body: this.body
28756
+ async function fetchAndConfigureCredentials() {
28757
+ try {
28758
+ const i = await postCogInit(), { credentials: a, is_session_expired: s } = i;
28759
+ if (s)
28760
+ return {
28761
+ success: !1,
28762
+ isPermanent: !0,
28763
+ error: "Session expired. Please re-login."
28764
+ };
28765
+ if (!a)
28766
+ return {
28767
+ success: !1,
28768
+ isPermanent: !1,
28769
+ error: "No credentials returned from token API"
28770
+ };
28771
+ const { AccessKeyId: n, SecretKey: r, SessionToken: c } = a;
28772
+ return configureAWS({
28773
+ accessKeyId: n,
28774
+ secretKey: r,
28775
+ sessionToken: c
28776
+ }), { success: !0, isPermanent: !1 };
28777
+ } catch (i) {
28778
+ return {
28779
+ success: !1,
28780
+ isPermanent: !1,
28781
+ error: i instanceof Error ? i.message : "Failed to fetch credentials"
28645
28782
  };
28646
28783
  }
28647
- async authHeader() {
28648
- return [
28649
- "AWS4-HMAC-SHA256 Credential=" + this.accessKeyId + "/" + this.credentialString,
28650
- "SignedHeaders=" + this.signedHeaders,
28651
- "Signature=" + await this.signature()
28652
- ].join(", ");
28653
- }
28654
- async signature() {
28655
- const a = this.datetime.slice(0, 8), s = [this.secretAccessKey, a, this.region, this.service].join();
28656
- let n = this.cache.get(s);
28657
- if (!n) {
28658
- const r = await hmac("AWS4" + this.secretAccessKey, a), c = await hmac(r, this.region), u = await hmac(c, this.service);
28659
- n = await hmac(u, "aws4_request"), this.cache.set(s, n);
28660
- }
28661
- return buf2hex(await hmac(n, await this.stringToSign()));
28662
- }
28663
- async stringToSign() {
28664
- return [
28665
- "AWS4-HMAC-SHA256",
28666
- this.datetime,
28667
- this.credentialString,
28668
- buf2hex(await hash(await this.canonicalString()))
28669
- ].join(`
28670
- `);
28671
- }
28672
- async canonicalString() {
28673
- return [
28674
- this.method.toUpperCase(),
28675
- this.encodedPath,
28676
- this.encodedSearch,
28677
- this.canonicalHeaders + `
28678
- `,
28679
- this.signedHeaders,
28680
- await this.hexBodyHash()
28681
- ].join(`
28682
- `);
28683
- }
28684
- async hexBodyHash() {
28685
- let a = this.headers.get("X-Amz-Content-Sha256") || (this.service === "s3" && this.signQuery ? "UNSIGNED-PAYLOAD" : null);
28686
- if (a == null) {
28687
- if (this.body && typeof this.body != "string" && !("byteLength" in this.body))
28688
- throw new Error("body must be a string, ArrayBuffer or ArrayBufferView, unless you include the X-Amz-Content-Sha256 header");
28689
- a = buf2hex(await hash(this.body || ""));
28690
- }
28691
- return a;
28692
- }
28693
28784
  }
28694
- async function hmac(i, a) {
28695
- const s = await crypto.subtle.importKey(
28696
- "raw",
28697
- typeof i == "string" ? encoder.encode(i) : i,
28698
- { name: "HMAC", hash: { name: "SHA-256" } },
28699
- !1,
28700
- ["sign"]
28701
- );
28702
- return crypto.subtle.sign("HMAC", s, encoder.encode(a));
28703
- }
28704
- async function hash(i) {
28705
- return crypto.subtle.digest("SHA-256", typeof i == "string" ? encoder.encode(i) : i);
28706
- }
28707
- const HEX_CHARS = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"];
28708
- function buf2hex(i) {
28709
- const a = new Uint8Array(i);
28710
- let s = "";
28711
- for (let n = 0; n < a.length; n++) {
28712
- const r = a[n];
28713
- s += HEX_CHARS[r >>> 4 & 15], s += HEX_CHARS[r & 15];
28714
- }
28715
- return s;
28716
- }
28717
- function encodeRfc3986(i) {
28718
- return i.replace(/[!'()*]/g, (a) => "%" + a.charCodeAt(0).toString(16).toUpperCase());
28719
- }
28720
- function guessServiceRegion(i, a) {
28721
- const { hostname: s, pathname: n } = i;
28722
- if (s.endsWith(".on.aws")) {
28723
- const m = s.match(/^[^.]{1,63}\.lambda-url\.([^.]{1,63})\.on\.aws$/);
28724
- return m != null ? ["lambda", m[1] || ""] : ["", ""];
28725
- }
28726
- if (s.endsWith(".r2.cloudflarestorage.com"))
28727
- return ["s3", "auto"];
28728
- if (s.endsWith(".backblazeb2.com")) {
28729
- const m = s.match(/^(?:[^.]{1,63}\.)?s3\.([^.]{1,63})\.backblazeb2\.com$/);
28730
- return m != null ? ["s3", m[1] || ""] : ["", ""];
28785
+ async function uploadToS3(i) {
28786
+ const { s3BucketName: a, fileBlob: s, fileName: n, txnID: r, businessID: c } = i, u = getConfiguredAwsCredentials();
28787
+ if (!u) {
28788
+ const o = new Error("AWS credentials not configured");
28789
+ throw o.code = "CredentialsError", o;
28790
+ }
28791
+ const { accessKeyId: m, secretKey: y, sessionToken: l } = u, p = new AwsClient({
28792
+ accessKeyId: m,
28793
+ secretAccessKey: y,
28794
+ sessionToken: l,
28795
+ region: "ap-south-1",
28796
+ service: "s3"
28797
+ }), t = `https://${a}.s3.ap-south-1.amazonaws.com/${n}`, e = await p.fetch(t, {
28798
+ method: "PUT",
28799
+ body: s,
28800
+ headers: {
28801
+ "Content-Type": s.type || "application/octet-stream",
28802
+ "x-amz-meta-txnid": r,
28803
+ "x-amz-meta-bid": c
28804
+ }
28805
+ });
28806
+ if (!e.ok) {
28807
+ const o = new Error(e.statusText);
28808
+ throw o.statusCode = e.status, o.code = e.status === 403 ? "ExpiredToken" : "UploadError", o;
28731
28809
  }
28732
- const r = s.replace("dualstack.", "").match(/([^.]{1,63})\.(?:([^.]{0,63})\.)?amazonaws\.com(?:\.cn)?$/);
28733
- let c = r && r[1] || "", u = r && r[2];
28734
- if (u === "us-gov")
28735
- u = "us-gov-west-1";
28736
- else if (u === "s3" || u === "s3-accelerate")
28737
- u = "us-east-1", c = "s3";
28738
- else if (c === "iot")
28739
- s.startsWith("iot.") ? c = "execute-api" : s.startsWith("data.jobs.iot.") ? c = "iot-jobs-data" : c = n === "/mqtt" ? "iotdevicegateway" : "iotdata";
28740
- else if (c === "autoscaling") {
28741
- const m = (a.get("X-Amz-Target") || "").split(".")[0];
28742
- m === "AnyScaleFrontendService" ? c = "application-autoscaling" : m === "AnyScaleScalingPlannerFrontendService" && (c = "autoscaling-plans");
28743
- } else u == null && c.startsWith("s3-") ? (u = c.slice(3).replace(/^fips-|^external-1/, ""), c = "s3") : c.endsWith("-fips") ? c = c.slice(0, -5) : u && /-\d$/.test(c) && !/-\d$/.test(u) && ([c, u] = [u, c]);
28744
- return [HOST_SERVICES[c] || c, u || ""];
28810
+ return e;
28745
28811
  }
28746
- async function s3RetryWrapper(i, a, s, n, r = !1) {
28747
- try {
28748
- return await i();
28749
- } catch (c) {
28750
- if (console.log(JSON.stringify(c, null, 2), "file upload - s3RetryWrapper - error"), n >= a)
28751
- throw c;
28752
- if (r) {
28753
- if (c.statusCode >= 400)
28754
- throw c;
28755
- } else {
28756
- const u = c.code, m = c.statusCode;
28757
- if (u === "ExpiredToken" || m >= 400)
28758
- try {
28759
- const y = await postCogInit(), { credentials: l, code: p } = y;
28760
- if (p === 401) {
28761
- const t = new Error("Auth token expired");
28762
- throw t.statusCode = 401, t.code = "AuthTokenExpired", t;
28763
- }
28764
- l && configureAWS({
28765
- accessKeyId: l.AccessKeyId,
28766
- secretKey: l.SecretKey,
28767
- sessionToken: l.SessionToken
28768
- });
28769
- } catch (y) {
28770
- throw y;
28812
+ async function uploadFileToS3(i, a = {}) {
28813
+ const { maxRetries: s = 3, initialDelay: n = 2e3 } = a;
28814
+ let r = null;
28815
+ for (let c = 0; c <= s; c++)
28816
+ try {
28817
+ if (!getConfiguredAwsCredentials()) {
28818
+ console.log(`[S3UploadService] No credentials, fetching... (attempt ${c + 1})`);
28819
+ const l = await fetchAndConfigureCredentials();
28820
+ if (!l.success) {
28821
+ if (l.isPermanent)
28822
+ return {
28823
+ error: l.error,
28824
+ code: 401,
28825
+ canRetry: !1
28826
+ };
28827
+ throw new Error(l.error || "Failed to fetch credentials");
28771
28828
  }
28829
+ }
28830
+ return {
28831
+ success: (await uploadToS3(i)).headers.get("ETag") || "Upload successful",
28832
+ canRetry: !1
28833
+ };
28834
+ } catch (u) {
28835
+ const m = classifyError(u);
28836
+ if (r = m, console.log(
28837
+ `[S3UploadService] Attempt ${c + 1}/${s + 1} failed:`,
28838
+ m.message,
28839
+ `(permanent: ${m.isPermanent})`
28840
+ ), m.isPermanent)
28841
+ return {
28842
+ error: m.message,
28843
+ code: m.code,
28844
+ canRetry: !1
28845
+ };
28846
+ if (c >= s)
28847
+ break;
28848
+ console.log("[S3UploadService] Refreshing credentials before retry...");
28849
+ const y = await fetchAndConfigureCredentials();
28850
+ if (!y.success && y.isPermanent)
28851
+ return {
28852
+ error: y.error,
28853
+ code: 401,
28854
+ canRetry: !1
28855
+ };
28856
+ console.log(`[S3UploadService] Waiting ${n}ms before retry...`), await new Promise((l) => setTimeout(l, n));
28772
28857
  }
28773
- return await new Promise((u) => setTimeout(u, s)), s3RetryWrapper(i, a, s, n + 1);
28774
- }
28858
+ return {
28859
+ error: r?.message || "Upload failed after all retries",
28860
+ code: r?.code || 500,
28861
+ canRetry: !0
28862
+ };
28775
28863
  }
28776
- const pushFilesToS3V2 = async ({
28777
- s3BucketName: i,
28778
- fileBlob: a,
28779
- fileName: s,
28780
- txnID: n,
28781
- businessID: r,
28782
- is_shared_worker: c = !1
28783
- }) => {
28784
- try {
28785
- const u = getConfiguredAwsCredentials();
28786
- if (!u)
28787
- throw new Error("AWS credentials are not configured. Call postCogInit/configureAWS first.");
28788
- const { accessKeyId: m, secretKey: y, sessionToken: l } = u, p = new AwsClient({
28789
- accessKeyId: m,
28790
- secretAccessKey: y,
28791
- sessionToken: l,
28792
- region: "ap-south-1",
28793
- service: "s3"
28794
- }), t = `https://${i}.s3.ap-south-1.amazonaws.com/${s}`;
28795
- return { success: (await s3RetryWrapper(() => new Promise((h, g) => {
28796
- p.fetch(t, {
28797
- method: "PUT",
28798
- body: a,
28799
- headers: {
28800
- "Content-Type": a.type || "application/octet-stream",
28801
- "x-amz-meta-txnid": n,
28802
- "x-amz-meta-bid": r
28803
- }
28804
- }).then((b) => {
28805
- if (!b.ok) {
28806
- const f = {
28807
- statusCode: b.status,
28808
- message: b.statusText,
28809
- // Normalise shape so s3RetryWrapper can treat this as an expired token
28810
- // (matches legacy AWS SDK error.code === 'ExpiredToken' handling).
28811
- code: "ExpiredToken"
28812
- };
28813
- g(f);
28814
- return;
28815
- }
28816
- h(b);
28817
- }).catch(g);
28818
- }), 3, 2e3, 0, c)).headers.get("ETag") || "Upload successful" };
28819
- } catch (u) {
28820
- const m = JSON.stringify(u, null, 2);
28821
- return console.error("pushFilesToS3V2 error =>", m), u.statusCode === 401 || u.code === "AuthTokenExpired" ? {
28822
- error: "Authentication token expired. Please call updateAuthTokens with a new token.",
28823
- errorCode: "AuthTokenExpired",
28824
- code: 401
28825
- } : u.statusCode && u.statusCode >= 400 ? {
28826
- error: `Expired token! ${m}`,
28827
- errorCode: "ExpiredToken",
28828
- code: u.statusCode || u.code
28829
- } : {
28830
- error: `Something went wrong! ${m}`,
28831
- code: u.statusCode || u.code
28832
- };
28833
- }
28834
- };
28835
28864
  function Xa(i) {
28836
28865
  return new Int8Array(i);
28837
28866
  }
@@ -38488,7 +38517,7 @@ const compressAudioToMp3 = (i) => {
38488
38517
  };
38489
38518
  class AudioFileManager {
38490
38519
  constructor() {
38491
- this.txnID = "", this.filePath = "", this.audioChunks = [], this.uploadPromises = [], this.successfulUploads = [], this.totalRawSamples = 0, this.totalRawFrames = 0, this.totalInsertedSamples = 0, this.totalInsertedFrames = 0, this.businessID = "", this.isAWSConfigured = !1, this.sharedWorkerInstance = null, this.initialiseClassInstance();
38520
+ this.txnID = "", this.filePath = "", this.audioChunks = [], this.uploadPromises = [], this.successfulUploads = [], this.totalRawSamples = 0, this.totalRawFrames = 0, this.totalInsertedSamples = 0, this.totalInsertedFrames = 0, this.businessID = "", this.sharedWorkerInstance = null, this.initialiseClassInstance();
38492
38521
  }
38493
38522
  initialiseClassInstance() {
38494
38523
  this.audioChunks = [], this.uploadPromises = [], this.successfulUploads = [], this.totalInsertedFrames = 0, this.totalInsertedSamples = 0, this.totalRawSamples = 0, this.totalRawFrames = 0;
@@ -38552,6 +38581,34 @@ class AudioFileManager {
38552
38581
  });
38553
38582
  return;
38554
38583
  }
38584
+ case SHARED_WORKER_ACTION.REQUEST_TOKEN_REFRESH: {
38585
+ console.log("[AudioFileManager] Worker requested token refresh");
38586
+ try {
38587
+ const u = await postCogInit(), { credentials: m, is_session_expired: y } = u;
38588
+ if (y || !m) {
38589
+ this.sharedWorkerInstance?.port.postMessage({
38590
+ action: SHARED_WORKER_ACTION.TOKEN_REFRESH_ERROR,
38591
+ error: "Session expired or no credentials"
38592
+ });
38593
+ return;
38594
+ }
38595
+ const { AccessKeyId: l, SecretKey: p, SessionToken: t } = m;
38596
+ this.sharedWorkerInstance?.port.postMessage({
38597
+ action: SHARED_WORKER_ACTION.TOKEN_REFRESH_SUCCESS,
38598
+ payload: {
38599
+ accessKeyId: l,
38600
+ secretKey: p,
38601
+ sessionToken: t
38602
+ }
38603
+ }), console.log("[AudioFileManager] Token refresh successful, sent to worker");
38604
+ } catch (u) {
38605
+ console.error("[AudioFileManager] Token refresh failed:", u), this.sharedWorkerInstance?.port.postMessage({
38606
+ action: SHARED_WORKER_ACTION.TOKEN_REFRESH_ERROR,
38607
+ error: u instanceof Error ? u.message : "Token refresh failed"
38608
+ });
38609
+ }
38610
+ return;
38611
+ }
38555
38612
  case SHARED_WORKER_ACTION.UPLOAD_FILE_WITH_WORKER_SUCCESS: {
38556
38613
  const {
38557
38614
  fileCount: u,
@@ -38606,8 +38663,6 @@ class AudioFileManager {
38606
38663
  audioFrames: void 0,
38607
38664
  status: "failure",
38608
38665
  response: r.response.error || "Upload failed"
38609
- }), r.response.errorCode === "ExpiredToken" && this.setupAWSConfiguration({
38610
- is_shared_worker: !0
38611
38666
  }));
38612
38667
  }
38613
38668
  }
@@ -38620,30 +38675,12 @@ class AudioFileManager {
38620
38675
  ) : console.error("Error creating shared worker instance:", s), !1;
38621
38676
  }
38622
38677
  }
38623
- async setupAWSConfiguration({ is_shared_worker: a }) {
38624
- try {
38625
- const s = await postCogInit(), { credentials: n, is_session_expired: r } = s;
38626
- if (r || !n)
38627
- return this.isAWSConfigured = !1, !1;
38628
- const { AccessKeyId: c, SecretKey: u, SessionToken: m } = n;
38629
- return a ? this.sharedWorkerInstance?.port.postMessage({
38630
- action: SHARED_WORKER_ACTION.CONFIGURE_AWS,
38631
- payload: {
38632
- accessKeyId: c,
38633
- secretKey: u,
38634
- sessionToken: m
38635
- }
38636
- }) : configureAWS({
38637
- accessKeyId: c,
38638
- secretKey: u,
38639
- sessionToken: m
38640
- }), this.isAWSConfigured = !0, n;
38641
- } catch (s) {
38642
- return console.error("%c Line:198 🥃 error", "color:#42b983", s), this.isAWSConfigured = !1, !1;
38643
- }
38678
+ terminateSharedWorkerInstance() {
38679
+ this.sharedWorkerInstance && (this.sharedWorkerInstance.port.close(), this.sharedWorkerInstance = null);
38644
38680
  }
38645
38681
  /**
38646
- * Upload a chunk of audio data to S3 in main thread
38682
+ * Upload a chunk of audio data to S3 in main thread.
38683
+ * Credentials are handled automatically by the S3UploadService.
38647
38684
  */
38648
38685
  async uploadAudioChunkInMain({
38649
38686
  audioFrames: a,
@@ -38665,13 +38702,12 @@ class AudioFileManager {
38665
38702
  chunkData: c
38666
38703
  }
38667
38704
  });
38668
- const y = GET_S3_BUCKET_NAME(), l = pushFilesToS3V2({
38705
+ const y = GET_S3_BUCKET_NAME(), l = uploadFileToS3({
38669
38706
  s3BucketName: y,
38670
38707
  fileBlob: u,
38671
38708
  fileName: r,
38672
38709
  txnID: this.txnID,
38673
- businessID: this.businessID,
38674
- is_shared_worker: !1
38710
+ businessID: this.businessID
38675
38711
  }).then((p) => (p.success ? (this.successfulUploads.push(s), n !== -1 && (this.audioChunks[n] = {
38676
38712
  ...this.audioChunks[n],
38677
38713
  audioFrames: void 0,
@@ -38715,7 +38751,8 @@ class AudioFileManager {
38715
38751
  };
38716
38752
  }
38717
38753
  /**
38718
- * Upload audio chunks to S3 in shared worker
38754
+ * Upload audio chunks to S3 in shared worker.
38755
+ * Credentials are handled automatically by the worker's S3UploadService.
38719
38756
  */
38720
38757
  async uploadAudioChunkInWorker({
38721
38758
  audioFrames: a,
@@ -38751,37 +38788,7 @@ class AudioFileManager {
38751
38788
  };
38752
38789
  }
38753
38790
  async uploadAudioToS3({ audioFrames: a, fileName: s, chunkIndex: n }) {
38754
- typeof SharedWorker > "u" || !SharedWorker || !this.sharedWorkerInstance ? (console.log("Shared Workers are NOT supported in this browser."), await this.uploadAudioToS3WithoutWorker({ audioFrames: a, fileName: s, chunkIndex: n })) : (console.log("Shared Workers are supported in this browser."), await this.uploadAudioToS3WithWorker({ audioFrames: a, fileName: s, chunkIndex: n }));
38755
- }
38756
- async uploadAudioToS3WithWorker({
38757
- audioFrames: a,
38758
- fileName: s,
38759
- chunkIndex: n
38760
- }) {
38761
- try {
38762
- if (!this.isAWSConfigured && !await this.setupAWSConfiguration({
38763
- is_shared_worker: !0
38764
- }))
38765
- throw new Error("Failed to configure AWS");
38766
- await this.uploadAudioChunkInWorker({ audioFrames: a, fileName: s, chunkIndex: n });
38767
- } catch (r) {
38768
- console.error("Error uploading audio to S3: uploadAudioToS3WithWorker: ", r), await this.uploadAudioToS3WithoutWorker({ audioFrames: a, fileName: s, chunkIndex: n });
38769
- }
38770
- }
38771
- async uploadAudioToS3WithoutWorker({
38772
- audioFrames: a,
38773
- fileName: s,
38774
- chunkIndex: n
38775
- }) {
38776
- try {
38777
- if (!this.isAWSConfigured && !await this.setupAWSConfiguration({
38778
- is_shared_worker: !1
38779
- }))
38780
- throw new Error("Failed to configure AWS");
38781
- await this.uploadAudioChunkInMain({ audioFrames: a, fileName: s, chunkIndex: n });
38782
- } catch (r) {
38783
- console.error("Error uploading audio to S3:", r);
38784
- }
38791
+ typeof SharedWorker > "u" || !SharedWorker || !this.sharedWorkerInstance ? (console.log("Using main thread for upload (SharedWorker not available)"), await this.uploadAudioChunkInMain({ audioFrames: a, fileName: s, chunkIndex: n })) : (console.log("Using SharedWorker for upload"), await this.uploadAudioChunkInWorker({ audioFrames: a, fileName: s, chunkIndex: n }));
38785
38792
  }
38786
38793
  /**
38787
38794
  * Download audio as a file to the user's device (for debugging)
@@ -38833,83 +38840,91 @@ class AudioFileManager {
38833
38840
  getTotalAudioChunks() {
38834
38841
  return this.audioChunks;
38835
38842
  }
38836
- // TODO: check this logic once
38837
38843
  /**
38838
- * Retry uploading failed files
38844
+ * Retry uploading failed files.
38845
+ * Returns list of files that still failed after retry.
38846
+ * Credentials are handled automatically by the S3UploadService.
38839
38847
  */
38840
38848
  async retryFailedUploads() {
38841
38849
  if (this.getFailedUploads().length === 0)
38842
38850
  return [];
38843
38851
  const s = EkaScribeStore$1.eventCallback, n = GET_S3_BUCKET_NAME();
38844
- if (this.sharedWorkerInstance)
38845
- this.audioChunks.forEach((r, c) => {
38846
- const { fileName: u, fileBlob: m, status: y, audioFrames: l } = r;
38847
- y != "success" && this.sharedWorkerInstance?.port.postMessage({
38848
- action: SHARED_WORKER_ACTION.UPLOAD_FILE_WITH_WORKER,
38849
- payload: {
38850
- s3BucketName: n,
38851
- audioFrames: l,
38852
- fileBlob: m,
38853
- fileName: `${this.filePath}/${u}`,
38854
- txnID: this.txnID,
38855
- businessID: this.businessID,
38856
- chunkIndex: c,
38857
- fileCount: u
38858
- }
38859
- });
38860
- });
38861
- else {
38862
- this.uploadPromises = [], s && s({
38863
- callback_type: CALLBACK_TYPE.FILE_UPLOAD_STATUS,
38864
- status: "info",
38865
- message: "Audio chunks count to display success/total file count",
38866
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
38867
- data: {
38868
- success: this.successfulUploads.length,
38869
- total: this.audioChunks.length
38852
+ return s && s({
38853
+ callback_type: CALLBACK_TYPE.FILE_UPLOAD_STATUS,
38854
+ status: "info",
38855
+ message: "Retrying failed uploads",
38856
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
38857
+ data: {
38858
+ success: this.successfulUploads.length,
38859
+ total: this.audioChunks.length
38860
+ }
38861
+ }), this.sharedWorkerInstance ? this.audioChunks.forEach((r, c) => {
38862
+ const { fileName: u, fileBlob: m, status: y, audioFrames: l } = r;
38863
+ y != "success" && this.sharedWorkerInstance?.port.postMessage({
38864
+ action: SHARED_WORKER_ACTION.UPLOAD_FILE_WITH_WORKER,
38865
+ payload: {
38866
+ s3BucketName: n,
38867
+ audioFrames: l,
38868
+ fileBlob: m,
38869
+ fileName: `${this.filePath}/${u}`,
38870
+ txnID: this.txnID,
38871
+ businessID: this.businessID,
38872
+ chunkIndex: c,
38873
+ fileCount: u
38870
38874
  }
38871
38875
  });
38872
- const r = GET_S3_BUCKET_NAME();
38873
- this.audioChunks.forEach((c, u) => {
38874
- const { fileName: m, fileBlob: y, status: l, audioFrames: p } = c;
38875
- if (l != "success") {
38876
- let t;
38877
- if (l === "failure" && (t = y), l === "pending") {
38878
- const e = compressAudioToMp3(p);
38879
- t = new Blob(e, {
38880
- type: AUDIO_EXTENSION_TYPE_MAP[OUTPUT_FORMAT]
38881
- });
38882
- }
38883
- if (t) {
38884
- const e = pushFilesToS3V2({
38885
- s3BucketName: r,
38886
- fileBlob: t,
38887
- fileName: `${this.filePath}/${m}`,
38888
- txnID: this.txnID,
38889
- businessID: this.businessID,
38890
- is_shared_worker: !1
38891
- }).then((o) => (o.success && (this.successfulUploads.push(m), s && s({
38892
- callback_type: CALLBACK_TYPE.FILE_UPLOAD_STATUS,
38893
- status: "info",
38894
- message: "Audio chunks count to display success/total file count",
38895
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
38896
- data: {
38897
- success: this.successfulUploads.length,
38898
- total: this.audioChunks.length
38899
- }
38900
- }), this.audioChunks[u] = {
38901
- ...this.audioChunks[u],
38902
- audioFrames: void 0,
38903
- fileBlob: void 0,
38904
- status: "success",
38905
- response: o.success
38906
- }), o));
38907
- this.uploadPromises.push(e);
38908
- }
38876
+ }) : (this.uploadPromises = [], this.audioChunks.forEach((r, c) => {
38877
+ const { fileName: u, fileBlob: m, status: y, audioFrames: l } = r;
38878
+ if (y != "success") {
38879
+ let p;
38880
+ if (y === "failure" && (p = m), y === "pending") {
38881
+ const t = compressAudioToMp3(l);
38882
+ p = new Blob(t, {
38883
+ type: AUDIO_EXTENSION_TYPE_MAP[OUTPUT_FORMAT]
38884
+ });
38909
38885
  }
38910
- });
38911
- }
38912
- return await this.waitForAllUploads(), this.getFailedUploads();
38886
+ if (p) {
38887
+ const t = uploadFileToS3({
38888
+ s3BucketName: n,
38889
+ fileBlob: p,
38890
+ fileName: `${this.filePath}/${u}`,
38891
+ txnID: this.txnID,
38892
+ businessID: this.businessID
38893
+ }).then((e) => (e.success ? (this.successfulUploads.push(u), s && s({
38894
+ callback_type: CALLBACK_TYPE.FILE_UPLOAD_STATUS,
38895
+ status: "success",
38896
+ message: "File uploaded successfully",
38897
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
38898
+ data: {
38899
+ success: this.successfulUploads.length,
38900
+ total: this.audioChunks.length,
38901
+ fileName: u,
38902
+ is_uploaded: !0
38903
+ }
38904
+ }), this.audioChunks[c] = {
38905
+ ...this.audioChunks[c],
38906
+ audioFrames: void 0,
38907
+ fileBlob: void 0,
38908
+ status: "success",
38909
+ response: e.success
38910
+ }) : s && s({
38911
+ callback_type: CALLBACK_TYPE.FILE_UPLOAD_STATUS,
38912
+ status: "error",
38913
+ message: e.error || "Upload failed",
38914
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
38915
+ error: {
38916
+ code: e.code || 500,
38917
+ msg: e.error || "Upload failed"
38918
+ },
38919
+ data: {
38920
+ fileName: u,
38921
+ is_uploaded: !1
38922
+ }
38923
+ }), e));
38924
+ this.uploadPromises.push(t);
38925
+ }
38926
+ }
38927
+ })), await this.waitForAllUploads(), this.getFailedUploads();
38913
38928
  }
38914
38929
  /**
38915
38930
  * Reset the upload state
@@ -38918,7 +38933,7 @@ class AudioFileManager {
38918
38933
  this.uploadPromises.forEach((a) => {
38919
38934
  a.catch(() => {
38920
38935
  });
38921
- }), this.sharedWorkerInstance && (this.sharedWorkerInstance.port.close(), this.sharedWorkerInstance = null), this.initialiseClassInstance(), this.txnID = "", this.filePath = "", this.businessID = "", this.isAWSConfigured = !1;
38936
+ }), this.sharedWorkerInstance && (this.sharedWorkerInstance.port.close(), this.sharedWorkerInstance = null), this.initialiseClassInstance(), this.txnID = "", this.filePath = "", this.businessID = "";
38922
38937
  }
38923
38938
  }
38924
38939
  var dist = {}, ortWeb_min = { exports: {} };
@@ -54709,13 +54724,12 @@ class SystemCompatibilityManager {
54709
54724
  c,
54710
54725
  n,
54711
54726
  r
54712
- )).success : !!(await pushFilesToS3V2({
54727
+ )).success : !!(await uploadFileToS3({
54713
54728
  s3BucketName: c,
54714
54729
  fileBlob: a,
54715
54730
  fileName: s,
54716
54731
  txnID: n,
54717
- businessID: r,
54718
- is_shared_worker: !1
54732
+ businessID: r
54719
54733
  })).success;
54720
54734
  } catch (a) {
54721
54735
  return console.error("Upload test failed:", a), !1;
@@ -55104,6 +55118,9 @@ const Ur = class Ur {
55104
55118
  throw console.error("Error running compatibility test:", n), n;
55105
55119
  }
55106
55120
  }
55121
+ async destroySharedWorker() {
55122
+ this.audioFileManagerInstance && this.audioFileManagerInstance.terminateSharedWorkerInstance();
55123
+ }
55107
55124
  };
55108
55125
  Ur.instance = null;
55109
55126
  let EkaScribe = Ur;