UNPKG

demoaugnitoambientsdk

Version:

Use this typescript SDK to integrate Augnito’s Ambient Tech within your EMR. To get access credentials or know more about how Augnito Ambient can benefit you, please visit our website and connect with our sales team: https://augnito.ai/

1,569 lines 58.4 kB
/******************************************************************************
Copyright (c) Microsoft Corporation.

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */

function __awaiter(thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
}

typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
    var e = new Error(message);
    return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};

class socketConfig {
    constructor(_config) {
        this._config = _config;
        this.wssBaseURL = `wss://${_config.server}/ambient/stream-job`;
    }
    prepareWSSURL(_filetype, _noteparams) {
        let WSSURL = this.wssBaseURL;
        WSSURL += `?filetype=${_filetype}`;
        WSSURL += `&noteparams=${_noteparams}`;
        WSSURL += `&subscriptioncode=${this._config.subscriptionCode}`;
        WSSURL += `&accesskey=${this._config.accessKey}`;
        WSSURL += `&usertag=${this._config.userTag}`;
        return WSSURL;
    }
}

function unwrapExports (x) {
	return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
}

function createCommonjsModule(fn, module) {
	return module = { exports: {} }, fn(module, module.exports), module.exports;
}

var Guard_1 = createCommonjsModule(function (module, exports) {

  Object.defineProperty(exports, "__esModule", {
    value: true
  });
  exports.Guard = void 0;
  class Guard {
    constructor() {
      // Constructor is private
    }
    static get Against() {
      if (!Guard.instance) {
        Guard.instance = new Guard();
      }
      return Guard.instance;
    }
    NullOrUndefined(value, paramName) {
      if (value === null) throw new TypeError(`${paramName} is null`);
      if (value === undefined) throw new TypeError(`${paramName} is undefined`);
      return value;
    }
    NullOrEmpty(value, paramName) {
      value = Guard.Against.NullOrUndefined(value, paramName);
      if (!value) throw new TypeError(`${paramName} is empty`);
      return value;
    }
  }
  exports.Guard = Guard;
});
unwrapExports(Guard_1);
var Guard_2 = Guard_1.Guard;

class AmbientRestAPI {
    constructor(_config) {
        this._config = _config;
        this._baseUrl = `https://${_config.server}/ambient`;
    }
    getURL(path) {
        return `${this._baseUrl}${path}`;
    }
    makePostRequest(url, requestData) {
        return __awaiter(this, void 0, void 0, function* () {
            try {
                const response = yield fetch(url, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(requestData)
                });
                if (!response.ok) {
                    throw new Error(`HTTP error! Status: ${response.status}`);
                }
                return yield response.json();
            }
            catch (error) {
                throw error;
            }
        });
    }
    GetNoteParams() {
        return __awaiter(this, void 0, void 0, function* () {
            const url = this.getURL('/note-params');
            const requestData = {
                SubscriptionCode: this._config.subscriptionCode,
                AccessKey: this._config.accessKey,
                UserTag: this._config.userTag
            };
            return yield this.makePostRequest(url, requestData);
        });
    }
    FetchJob(_jobId) {
        return __awaiter(this, void 0, void 0, function* () {
            Guard_2.Against.NullOrEmpty(_jobId, 'Job Id');
            const url = this.getURL('/fetch-job');
            const requestData = {
                SubscriptionCode: this._config.subscriptionCode,
                AccessKey: this._config.accessKey,
                UserTag: this._config.userTag,
                JobID: _jobId
            };
            return yield this.makePostRequest(url, requestData);
        });
    }
    SendFinalNote(_jobId, _noteDate) {
        return __awaiter(this, void 0, void 0, function* () {
            Guard_2.Against.NullOrEmpty(_jobId, 'Job Id');
            Guard_2.Against.NullOrEmpty(_noteDate, 'Note Data');
            const url = this.getURL('/send-final-note');
            const requestData = {
                SubscriptionCode: this._config.subscriptionCode,
                AccessKey: this._config.accessKey,
                UserTag: this._config.userTag,
                JobID: _jobId,
                SoapData: _noteDate
            };
            return yield this.makePostRequest(url, requestData);
        });
    }
}

var Logger_1 = createCommonjsModule(function (module, exports) {

  Object.defineProperty(exports, "__esModule", {
    value: true
  });
  exports.Logger = void 0;
  /* eslint-disable @typescript-eslint/no-explicit-any */
  /* eslint-disable no-console */
  class Logger {
    static log(message, tag) {
      const logTag = tag != null ? tag : this.defaultTag;
      console.log(`${logTag}:`, message);
    }
    static error(message, tag) {
      const logTag = tag != null ? tag : this.defaultTag;
      console.error(`${logTag}:`, message);
    }
  }
  exports.Logger = Logger;
  Logger.defaultTag = 'AugnitoAmbientSDK';
});
unwrapExports(Logger_1);
var Logger_2 = Logger_1.Logger;

function _regeneratorRuntime() {
  _regeneratorRuntime = function () {
    return e;
  };
  var t,
    e = {},
    r = Object.prototype,
    n = r.hasOwnProperty,
    o = Object.defineProperty || function (t, e, r) {
      t[e] = r.value;
    },
    i = "function" == typeof Symbol ? Symbol : {},
    a = i.iterator || "@@iterator",
    c = i.asyncIterator || "@@asyncIterator",
    u = i.toStringTag || "@@toStringTag";
  function define(t, e, r) {
    return Object.defineProperty(t, e, {
      value: r,
      enumerable: !0,
      configurable: !0,
      writable: !0
    }), t[e];
  }
  try {
    define({}, "");
  } catch (t) {
    define = function (t, e, r) {
      return t[e] = r;
    };
  }
  function wrap(t, e, r, n) {
    var i = e && e.prototype instanceof Generator ? e : Generator,
      a = Object.create(i.prototype),
      c = new Context(n || []);
    return o(a, "_invoke", {
      value: makeInvokeMethod(t, r, c)
    }), a;
  }
  function tryCatch(t, e, r) {
    try {
      return {
        type: "normal",
        arg: t.call(e, r)
      };
    } catch (t) {
      return {
        type: "throw",
        arg: t
      };
    }
  }
  e.wrap = wrap;
  var h = "suspendedStart",
    l = "suspendedYield",
    f = "executing",
    s = "completed",
    y = {};
  function Generator() {}
  function GeneratorFunction() {}
  function GeneratorFunctionPrototype() {}
  var p = {};
  define(p, a, function () {
    return this;
  });
  var d = Object.getPrototypeOf,
    v = d && d(d(values([])));
  v && v !== r && n.call(v, a) && (p = v);
  var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p);
  function defineIteratorMethods(t) {
    ["next", "throw", "return"].forEach(function (e) {
      define(t, e, function (t) {
        return this._invoke(e, t);
      });
    });
  }
  function AsyncIterator(t, e) {
    function invoke(r, o, i, a) {
      var c = tryCatch(t[r], t, o);
      if ("throw" !== c.type) {
        var u = c.arg,
          h = u.value;
        return h && "object" == typeof h && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) {
          invoke("next", t, i, a);
        }, function (t) {
          invoke("throw", t, i, a);
        }) : e.resolve(h).then(function (t) {
          u.value = t, i(u);
        }, function (t) {
          return invoke("throw", t, i, a);
        });
      }
      a(c.arg);
    }
    var r;
    o(this, "_invoke", {
      value: function (t, n) {
        function callInvokeWithMethodAndArg() {
          return new e(function (e, r) {
            invoke(t, n, e, r);
          });
        }
        return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();
      }
    });
  }
  function makeInvokeMethod(e, r, n) {
    var o = h;
    return function (i, a) {
      if (o === f) throw Error("Generator is already running");
      if (o === s) {
        if ("throw" === i) throw a;
        return {
          value: t,
          done: !0
        };
      }
      for (n.method = i, n.arg = a;;) {
        var c = n.delegate;
        if (c) {
          var u = maybeInvokeDelegate(c, n);
          if (u) {
            if (u === y) continue;
            return u;
          }
        }
        if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) {
          if (o === h) throw o = s, n.arg;
          n.dispatchException(n.arg);
        } else "return" === n.method && n.abrupt("return", n.arg);
        o = f;
        var p = tryCatch(e, r, n);
        if ("normal" === p.type) {
          if (o = n.done ? s : l, p.arg === y) continue;
          return {
            value: p.arg,
            done: n.done
          };
        }
        "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg);
      }
    };
  }
  function maybeInvokeDelegate(e, r) {
    var n = r.method,
      o = e.iterator[n];
    if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y;
    var i = tryCatch(o, e.iterator, r.arg);
    if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y;
    var a = i.arg;
    return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y);
  }
  function pushTryEntry(t) {
    var e = {
      tryLoc: t[0]
    };
    1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e);
  }
  function resetTryEntry(t) {
    var e = t.completion || {};
    e.type = "normal", delete e.arg, t.completion = e;
  }
  function Context(t) {
    this.tryEntries = [{
      tryLoc: "root"
    }], t.forEach(pushTryEntry, this), this.reset(!0);
  }
  function values(e) {
    if (e || "" === e) {
      var r = e[a];
      if (r) return r.call(e);
      if ("function" == typeof e.next) return e;
      if (!isNaN(e.length)) {
        var o = -1,
          i = function next() {
            for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next;
            return next.value = t, next.done = !0, next;
          };
        return i.next = i;
      }
    }
    throw new TypeError(typeof e + " is not iterable");
  }
  return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", {
    value: GeneratorFunctionPrototype,
    configurable: !0
  }), o(GeneratorFunctionPrototype, "constructor", {
    value: GeneratorFunction,
    configurable: !0
  }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) {
    var e = "function" == typeof t && t.constructor;
    return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name));
  }, e.mark = function (t) {
    return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t;
  }, e.awrap = function (t) {
    return {
      __await: t
    };
  }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () {
    return this;
  }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) {
    void 0 === i && (i = Promise);
    var a = new AsyncIterator(wrap(t, r, n, o), i);
    return e.isGeneratorFunction(r) ? a : a.next().then(function (t) {
      return t.done ? t.value : a.next();
    });
  }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () {
    return this;
  }), define(g, "toString", function () {
    return "[object Generator]";
  }), e.keys = function (t) {
    var e = Object(t),
      r = [];
    for (var n in e) r.push(n);
    return r.reverse(), function next() {
      for (; r.length;) {
        var t = r.pop();
        if (t in e) return next.value = t, next.done = !1, next;
      }
      return next.done = !0, next;
    };
  }, e.values = values, Context.prototype = {
    constructor: Context,
    reset: function (e) {
      if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t);
    },
    stop: function () {
      this.done = !0;
      var t = this.tryEntries[0].completion;
      if ("throw" === t.type) throw t.arg;
      return this.rval;
    },
    dispatchException: function (e) {
      if (this.done) throw e;
      var r = this;
      function handle(n, o) {
        return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o;
      }
      for (var o = this.tryEntries.length - 1; o >= 0; --o) {
        var i = this.tryEntries[o],
          a = i.completion;
        if ("root" === i.tryLoc) return handle("end");
        if (i.tryLoc <= this.prev) {
          var c = n.call(i, "catchLoc"),
            u = n.call(i, "finallyLoc");
          if (c && u) {
            if (this.prev < i.catchLoc) return handle(i.catchLoc, !0);
            if (this.prev < i.finallyLoc) return handle(i.finallyLoc);
          } else if (c) {
            if (this.prev < i.catchLoc) return handle(i.catchLoc, !0);
          } else {
            if (!u) throw Error("try statement without catch or finally");
            if (this.prev < i.finallyLoc) return handle(i.finallyLoc);
          }
        }
      }
    },
    abrupt: function (t, e) {
      for (var r = this.tryEntries.length - 1; r >= 0; --r) {
        var o = this.tryEntries[r];
        if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) {
          var i = o;
          break;
        }
      }
      i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null);
      var a = i ? i.completion : {};
      return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a);
    },
    complete: function (t, e) {
      if ("throw" === t.type) throw t.arg;
      return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y;
    },
    finish: function (t) {
      for (var e = this.tryEntries.length - 1; e >= 0; --e) {
        var r = this.tryEntries[e];
        if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y;
      }
    },
    catch: function (t) {
      for (var e = this.tryEntries.length - 1; e >= 0; --e) {
        var r = this.tryEntries[e];
        if (r.tryLoc === t) {
          var n = r.completion;
          if ("throw" === n.type) {
            var o = n.arg;
            resetTryEntry(r);
          }
          return o;
        }
      }
      throw Error("illegal catch attempt");
    },
    delegateYield: function (e, r, n) {
      return this.delegate = {
        iterator: values(e),
        resultName: r,
        nextLoc: n
      }, "next" === this.method && (this.arg = t), y;
    }
  }, e;
}
function _toPrimitive(t, r) {
  if ("object" != typeof t || !t) return t;
  var e = t[Symbol.toPrimitive];
  if (void 0 !== e) {
    var i = e.call(t, r || "default");
    if ("object" != typeof i) return i;
    throw new TypeError("@@toPrimitive must return a primitive value.");
  }
  return ("string" === r ? String : Number)(t);
}
function _toPropertyKey(t) {
  var i = _toPrimitive(t, "string");
  return "symbol" == typeof i ? i : i + "";
}
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
  try {
    var info = gen[key](arg);
    var value = info.value;
  } catch (error) {
    reject(error);
    return;
  }
  if (info.done) {
    resolve(value);
  } else {
    Promise.resolve(value).then(_next, _throw);
  }
}
function _asyncToGenerator(fn) {
  return function () {
    var self = this,
      args = arguments;
    return new Promise(function (resolve, reject) {
      var gen = fn.apply(self, args);
      function _next(value) {
        asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
      }
      function _throw(err) {
        asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
      }
      _next(undefined);
    });
  };
}
function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}
function _defineProperties(target, props) {
  for (var i = 0; i < props.length; i++) {
    var descriptor = props[i];
    descriptor.enumerable = descriptor.enumerable || false;
    descriptor.configurable = true;
    if ("value" in descriptor) descriptor.writable = true;
    Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
  }
}
function _createClass(Constructor, protoProps, staticProps) {
  if (protoProps) _defineProperties(Constructor.prototype, protoProps);
  if (staticProps) _defineProperties(Constructor, staticProps);
  Object.defineProperty(Constructor, "prototype", {
    writable: false
  });
  return Constructor;
}

var LOOP_AUDIO = true;
var WORKLET_PROCESSOR = "worklet-processor";
var SAMPLE_RATE = 16000;
var EOS_MSG = "EOS";
var DONE_MSG = "DONE";
var PAUSE_MSG = "PAUSE";
var STOP_MSG = "STOP";
var CHANNEL_COUNT = 1;
var BITS_PER_SAMPLE = 16;
var NOISE_SUPPRESS_ENABLED = false;
var KEEP_ALIVE_TIMEOUT = 120000;
var IDLE_THREAD_INTERVAL = 10000;
var CONSUME_INTERVAL = 100;
var CONNECT_RETRY_TIMEOUT = 10000;
var HEALTHCHECK_INTERVAL = 1000;
var SOCKET_TIMEOUT = 10000;

var Executor = /*#__PURE__*/function () {
  function Executor(wsUrl, enableLogs, eosMessage, socketTimeoutInterval, onFinalResult, onPartialResult, onError, onSessionEvent, onOtherResults) {
    _classCallCheck(this, Executor);
    this.worker;
    this.wsUrl = wsUrl;
    this.onFinalResultCallback = onFinalResult;
    this.onErrorCallback = onError;
    this.onPartialResultCallback = onPartialResult;
    this.onSessionEventCallback = onSessionEvent;
    this.onOtherResultsCallback = onOtherResults;
    this.lastSent;
    this.heavyOp;
    this.idleLoop;
    this.enableLogs = enableLogs;
    this.eosMessage = eosMessage ? eosMessage : EOS_MSG;
    this.socketTimeoutInterval = socketTimeoutInterval ? socketTimeoutInterval : SOCKET_TIMEOUT;
  }

  // main-thread
  return _createClass(Executor, [{
    key: "Start",
    value: function Start() {
      var _this$heavyOp,
        _this = this;
      this.worker = new Worker(URL.createObjectURL(new Blob(["\n            const DONE_MSG = \"".concat(DONE_MSG, "\";\n            const EOS_MSG = \"{'JobAction': 'EOS','Status': 0,'Type': 'meta'}\";\n            const CONNECT_RETRY_TIMEOUT = ").concat(CONNECT_RETRY_TIMEOUT, ";\n            const CONSUME_INTERVAL = ").concat(CONSUME_INTERVAL, ";\n            const HEALTHCHECK_INTERVAL = ").concat(HEALTHCHECK_INTERVAL, ";\n            const SOCKET_TIMEOUT = ").concat(this.socketTimeoutInterval, ";\n            const wsUrl = \"").concat(this.wsUrl, "\";\n            const heavyOp = ").concat((_this$heavyOp = this.heavyOp) === null || _this$heavyOp === void 0 ? void 0 : _this$heavyOp.toString(), ";\n            const enableLogs = ").concat(this.enableLogs, ";\n            ("), function () {
        var lastConnect;
        var lastDataSent;
        var lastDataReceived;
        var queue = [];
        var ws;
        var isDone = false;
        var JobID = "";
        initConnect();

        // message received from main-thread
        self.onmessage = function (event) {
          if (event.data === "DONE") {
            add(EOS_MSG);
            JobID = "";
            if (enableLogs) {
              console.log("Worker received DONE, time to terminate...");
            }
            isDone = true;
          } else add(event.data);
        };
        function initConnect() {
          lastConnect = +new Date();
          if (JobID != "") {
            ws = new WebSocket(wsUrl + "&jobid=" + JobID);
          } else {
            ws = new WebSocket(wsUrl);
          }
          ws.onopen = function (event) {
            if (enableLogs) {
              console.log("WebSocket connection established: " + JSON.stringify(event));
            }
          };
          ws.onmessage = function (message) {
            if (enableLogs) {
              console.log("Message from server: " + JSON.stringify(message.data));
            }
            lastDataReceived = +new Date();
            operate(message);
          };
          ws.onerror = function (error) {
            console.error("WebSocket error: ", error);
            self.postMessage({
              type: "error",
              data: error.toString()
            });
            // TODO may want to reinitialise
          };
          ws.onclose = function (event) {
            if (enableLogs) {
              console.log("WebSocket connection closed: " + JSON.stringify(event));
            }
            cleanup();
          };
          lastDataSent = +new Date();
          lastDataReceived = lastDataSent;
        }

        // TODO lose the interval and try reading from queue on-add and on-open.
        var consumer = setInterval(function () {
          while (queue.length > 0) {
            var data = queue.shift();
            var isSent = send(data);
            if (!isSent) {
              queue.unshift(data);
              break;
            }
          }
        }, CONSUME_INTERVAL);
        function send(data) {
          if (ws && ws.readyState === WebSocket.OPEN) {
            ws.send(data);
            // This needs to be done to keep the "lastDataReceived" value closer to the
            // first "lastDataSent" value after ASR is received from the server, so as to
            // not invoke the healthcheck loop and force close the connection.
            var currentTime = +new Date();
            if (lastDataSent <= lastDataReceived) {
              lastDataReceived = currentTime - 1;
            }
            lastDataSent = currentTime;
            return true;
          } else {
            if (data === "EOS") {
              if (enableLogs) {
                console.warn("Gulping ".concat(EOS_MSG, " as socket seems already closed..."));
              }
              cleanup();
              return true;
            }
            // console.error("WebSocket connection is not open...");
            if (+new Date() - lastConnect > 10000) {
              // log("...time to reconnect.");
              initConnect();
            }
            return false;
          }
        }
        function add(data) {
          queue.push(data);
        }
        function operate(message) {
          try {
            var data = JSON.parse(message.data);
            if (enableLogs) {
              console.log("[WORKER]: " + JSON.stringify(data));
            }
            if (data.Type == "meta") {
              if (data.JobID) {
                JobID = data.JobID;
                console.log("JobID:", JobID);
              }
              self.postMessage({
                type: "meta",
                data: message.data
              });
            } else if (data.Result && data.Result.Final) {
              // should not be called with "this", check worker construction for more info.
              var outputText = JSON.stringify(data.Result);
              if (heavyOp) {
                outputText = heavyOp(JSON.stringify(data.Result));
                console.log(outputText);
              }
              self.postMessage({
                type: "final",
                data: outputText
              });

              // message sent to main-thread
            } else if (data.Result && !data.Result.Final) {
              self.postMessage({
                type: "partial",
                data: data.Result.Transcript
              });
            } else if (data.Type == "ACK") {
              self.postMessage({
                type: "other",
                data: message.data
              });
            }
          } catch (e) {
            self.postMessage({
              type: "error",
              data: "invalid response"
            });
          }
        }
        var healthCheck = setInterval(function () {
          if (ws && ws.readyState === WebSocket.OPEN) {
            var currentTime = +new Date();
            if (lastDataSent > lastDataReceived && currentTime - lastDataReceived > 10000) {
              if (enableLogs) {
                console.error("No data received since more than ".concat(SOCKET_TIMEOUT / 1000, " secs, closing time..."));
              }
              ws.close();
            }
          }
        }, HEALTHCHECK_INTERVAL);
        function cleanup() {
          if (isDone) {
            clearInterval(consumer);
            clearInterval(healthCheck);
            self.close();
          }
        }
      }.toString(), ")();"], {
        type: "text/javascript"
      })));
      // message received from web-worker
      this.worker.onmessage = function (event) {
        if (_this.enableLogs) {
          console.log("[MAIN]: " + JSON.stringify(event.data));
        }
        var eventData = event.data;
        //   const asrText = document.getElementById("asrText");
        if (eventData.type == "final") _this.onFinalResultCallback(eventData.data);else if (eventData.type == "partial") _this.onPartialResultCallback(eventData.data);else if (eventData.type == "meta") _this.onSessionEventCallback(eventData.data);else if (eventData.type == "error") _this.onErrorCallback(eventData.data);else if (eventData.type == "other") _this.onOtherResultsCallback(eventData.data);
      };
      // main-thread
      this.idleLoop = setInterval(function () {
        var currentTime = +new Date();
        if (_this.lastSent && currentTime - _this.lastSent > KEEP_ALIVE_TIMEOUT) {
          _this.Send(_this.eosMessage);
          _this.lastSent = null;
          if (_this.enableLogs) {
            console.warn("No data sent since more than ".concat(KEEP_ALIVE_TIMEOUT / 1000, " secs, closing time..."));
          }
        }
      }, IDLE_THREAD_INTERVAL);
    }

    // main-thread
  }, {
    key: "Send",
    value: function Send(data) {
      this.lastSent = +new Date();
      if (data === "DONE") {
        // message sent to web-worker
        this.worker.postMessage(DONE_MSG);
        clearInterval(this.idleLoop);
      } else {
        // message sent to web-worker - transferrable
        this.worker.postMessage(data, [data]);
      }
    }

    // worker-thread
  }, {
    key: "process",
    value: function process() {}

    // log(event) {
    //   const data = `${new Date().toLocaleTimeString()}: ${event}`;
    //   console.log(data + "\n");
    // }
  }, {
    key: "HeavyOp",
    set: function set(heavyOp) {
      this.heavyOp = heavyOp;
    }
  }]);
}();

// worklet-thread
var worklet = "class MyAudioWorkletProcessor extends AudioWorkletProcessor {\n  constructor() {\n    super();\n    this.accumulator = [];\n    this.reset();\n    this.isProcessing = true;\n    // message received from main-thread\n    this.port.onmessage = (e) => {\n      console.log(\"Worklet received event: \", e.data);\n      if (this.sampleSize > 0) {\n        this.accumulator.push(this.sampleVal / this.sampleSize);\n      }\n      if (e.data == \"PAUSE\") {\n        // append silence to get last word ASR.\n        const silenceSize = 16000 * 2;\n        for (let i = 0; i < silenceSize; i++) {\n          this.accumulator.push(0);\n        }\n      }\n      this.send();\n      if (e.data == \"STOP\") {\n        // message sent to main-thread\n        this.port.postMessage(\"DONE\");\n        this.isProcessing = false;\n      }\n    };\n  }\n\n  static get parameterDescriptors() {\n    return [\n      {\n        name: \"scale\",\n        defaultValue: 1,\n        minValue: 1,\n        maxValue: 6,\n      },\n      {\n        name: \"bufferSizeInterval\",\n        defaultValue: 1,\n        minValue: 1,\n        maxValue: 100,\n      },\n    ];\n  }\n\n  // 128 frames\n  process(inputList, outputList, params) {\n    const input = inputList[0];\n    if (input && input.length && input[0].length) {\n      const output = outputList[0];\n      const scale = params.scale[0];\n      const bufferSizeInterval = params[\"bufferSizeInterval\"][0];\n      console.log(\"BufferSizeInterval\", bufferSizeInterval);\n      // Jackpot\n      input[0].forEach((float32Element) => {\n        const int16Element = Math.min(1, Math.max(-1, float32Element)) * 0x7fff;\n        this.sampleVal += int16Element;\n        this.sampleSize++;\n        if (this.sampleSize == scale) {\n          this.accumulator.push(this.sampleVal / this.sampleSize);\n          this.reset();\n        }\n\n        // Comment this when streaming microphone audio\n        // output[0][index] = float32Element;\n      });\n      if (this.accumulator.length >= 125 * 128 * bufferSizeInterval) {\n        this.send();\n      }\n    }\n    return this.isProcessing;\n  }\n\n  send() {\n    if (this.accumulator.length == 0) return;\n    const audioData = new Int16Array(this.accumulator);\n    // message sent to main-thread - transferrable\n    this.port.postMessage(audioData.buffer, [audioData.buffer]);\n    this.accumulator = [];\n    this.reset();\n  }\n\n  reset() {\n    this.sampleVal = 0;\n    this.sampleSize = 0;\n  }\n}\n\nregisterProcessor(\"worklet-processor\", MyAudioWorkletProcessor);";

// main-thread
var Streamer = /*#__PURE__*/function () {
  function Streamer(wsUrl, enableLogs, isDebug, bufferSizeInterval, eosMessage, socketTimeoutInterval, heavyOp, onFinalResult, onPartialResult, onError, onStateChanged, onSessionEvent, onOtherResults) {
    _classCallCheck(this, Streamer);
    this.audioContext = new AudioContext();
    if (wsUrl !== "") {
      this.executor = new Executor(wsUrl, enableLogs, eosMessage, socketTimeoutInterval, onFinalResult, onPartialResult, onError, onSessionEvent, onOtherResults);
      this.executor.HeavyOp = heavyOp;
      this.executor.Start();
    }
    this.source;
    this.processorNode;
    this.isPaused = false;
    // Uncomment to save recording
    this.audioData = [];
    this.isDebug = isDebug;
    this.enableLogs = enableLogs;
    this.onStateChanged = onStateChanged;
    this.bufferSizeInterval = bufferSizeInterval;
  }
  return _createClass(Streamer, [{
    key: "StartStream",
    value: function () {
      var _StartStream = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
        return _regeneratorRuntime().wrap(function _callee$(_context) {
          while (1) switch (_context.prev = _context.next) {
            case 0:
              this.log("New stream started...");
              // Uncomment to stream recorded audio
              // await this.createBufferedSourceNode();
              // Uncomment to stream microphone audio
              _context.next = 3;
              return this.createMediaStreamSourceNode();
            case 3:
              if (this.source) {
                _context.next = 6;
                break;
              }
              console.error("Error: unable to create source node");
              return _context.abrupt("return");
            case 6:
              _context.next = 8;
              return this.createProcessorNode();
            case 8:
              if (this.processorNode) {
                _context.next = 11;
                break;
              }
              console.error("Error: unable to create processor node");
              return _context.abrupt("return");
            case 11:
              this.onStateChanged(true);
              this.source.connect(this.processorNode).connect(this.audioContext.destination);
              this.log("AudioContext Sample Rate: " + this.audioContext.sampleRate);
            case 14:
            case "end":
              return _context.stop();
          }
        }, _callee, this);
      }));
      function StartStream() {
        return _StartStream.apply(this, arguments);
      }
      return StartStream;
    }()
  }, {
    key: "createBufferedSourceNode",
    value: function () {
      var _createBufferedSourceNode = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2() {
        var audioBuffer;
        return _regeneratorRuntime().wrap(function _callee2$(_context2) {
          while (1) switch (_context2.prev = _context2.next) {
            case 0:
              _context2.next = 2;
              return this.loadAudio();
            case 2:
              audioBuffer = _context2.sent;
              if (audioBuffer) {
                _context2.next = 6;
                break;
              }
              console.error("Error: unable to create audio buffer");
              return _context2.abrupt("return");
            case 6:
              this.source = this.audioContext.createBufferSource();
              this.source.buffer = audioBuffer;
              this.source.loop = LOOP_AUDIO;
              this.source.start();
            case 10:
            case "end":
              return _context2.stop();
          }
        }, _callee2, this);
      }));
      function createBufferedSourceNode() {
        return _createBufferedSourceNode.apply(this, arguments);
      }
      return createBufferedSourceNode;
    }()
  }, {
    key: "createMediaStreamSourceNode",
    value: function () {
      var _createMediaStreamSourceNode = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3() {
        var audioStream;
        return _regeneratorRuntime().wrap(function _callee3$(_context3) {
          while (1) switch (_context3.prev = _context3.next) {
            case 0:
              _context3.next = 2;
              return navigator.mediaDevices.getUserMedia({
                audio: {
                  channelCount: CHANNEL_COUNT,
                  noiseSuppression: NOISE_SUPPRESS_ENABLED
                  // sampleRate: SAMPLE_RATE,
                  // sampleSize: BITS_PER_SAMPLE,
                }
              });
            case 2:
              audioStream = _context3.sent;
              this.source = this.audioContext.createMediaStreamSource(audioStream);
            case 4:
            case "end":
              return _context3.stop();
          }
        }, _callee3, this);
      }));
      function createMediaStreamSourceNode() {
        return _createMediaStreamSourceNode.apply(this, arguments);
      }
      return createMediaStreamSourceNode;
    }()
  }, {
    key: "loadAudio",
    value: function () {
      var _loadAudio = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4() {
        var response, arrayBuffer, audioBuffer;
        return _regeneratorRuntime().wrap(function _callee4$(_context4) {
          while (1) switch (_context4.prev = _context4.next) {
            case 0:
              _context4.prev = 0;
              _context4.next = 3;
              return fetch("./radiology_speed_test.wav");
            case 3:
              response = _context4.sent;
              _context4.next = 6;
              return response.arrayBuffer();
            case 6:
              arrayBuffer = _context4.sent;
              _context4.next = 9;
              return this.audioContext.decodeAudioData(arrayBuffer);
            case 9:
              audioBuffer = _context4.sent;
              return _context4.abrupt("return", audioBuffer);
            case 13:
              _context4.prev = 13;
              _context4.t0 = _context4["catch"](0);
              console.error("Unable to fetch the audio file. Error: ".concat(_context4.t0.message));
              return _context4.abrupt("return", null);
            case 17:
            case "end":
              return _context4.stop();
          }
        }, _callee4, this, [[0, 13]]);
      }));
      function loadAudio() {
        return _loadAudio.apply(this, arguments);
      }
      return loadAudio;
    }()
  }, {
    key: "createProcessorNode",
    value: function () {
      var _createProcessorNode = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5() {
        var _this = this;
        var scaleParam, scale, bufferSizeIntervalParam;
        return _regeneratorRuntime().wrap(function _callee5$(_context5) {
          while (1) switch (_context5.prev = _context5.next) {
            case 0:
              _context5.prev = 0;
              _context5.next = 3;
              return this.audioContext.audioWorklet.addModule("data:application/javascript,".concat(encodeURIComponent(worklet)));
            case 3:
              this.processorNode = new AudioWorkletNode(this.audioContext, WORKLET_PROCESSOR);
              scaleParam = this.processorNode.parameters.get("scale");
              scale = Math.ceil(this.audioContext.sampleRate / SAMPLE_RATE);
              scaleParam.setValueAtTime(scale, this.audioContext.currentTime);
              bufferSizeIntervalParam = this.processorNode.parameters.get("bufferSizeInterval");
              bufferSizeIntervalParam.setValueAtTime(this.bufferSizeInterval, this.audioContext.currentTime);
              // message received from worklet-thread
              this.processorNode.port.onmessage = function (event) {
                if (event.data == DONE_MSG) {
                  _this.log("Worklet processing done, clearing resources...");
                  _this.cleanup();
                  // Uncomment to save recording
                  if (_this.isDebug) _this.saveAudio();
                }
                // Uncomment to save recording
                else {
                  if (_this.isDebug) {
                    new Int16Array(event.data).forEach(function (element) {
                      return _this.audioData.push(element);
                    });
                  }
                }
                if (_this.executor) _this.executor.Send(event.data);
              };
              _context5.next = 15;
              break;
            case 12:
              _context5.prev = 12;
              _context5.t0 = _context5["catch"](0);
              console.error("Error: Unable to create worklet node: ", _context5.t0);
            case 15:
            case "end":
              return _context5.stop();
          }
        }, _callee5, this, [[0, 12]]);
      }));
      function createProcessorNode() {
        return _createProcessorNode.apply(this, arguments);
      }
      return createProcessorNode;
    }()
  }, {
    key: "PauseStream",
    value: function () {
      var _PauseStream = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6() {
        return _regeneratorRuntime().wrap(function _callee6$(_context6) {
          while (1) switch (_context6.prev = _context6.next) {
            case 0:
              if (!(this.audioContext.state == "running")) {
                _context6.next = 6;
                break;
              }
              _context6.next = 3;
              return this.audioContext.suspend();
            case 3:
              this.onStateChanged(false);
              this.log("Stream paused...");
              // message sent to worklet-thread
              this.processorNode.port.postMessage(PAUSE_MSG);
            case 6:
              this.isPaused = true;
            case 7:
            case "end":
              return _context6.stop();
          }
        }, _callee6, this);
      }));
      function PauseStream() {
        return _PauseStream.apply(this, arguments);
      }
      return PauseStream;
    }()
  }, {
    key: "ResumeStream",
    value: function () {
      var _ResumeStream = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7() {
        return _regeneratorRuntime().wrap(function _callee7$(_context7) {
          while (1) switch (_context7.prev = _context7.next) {
            case 0:
              if (!(this.audioContext.state == "suspended")) {
                _context7.next = 5;
                break;
              }
              _context7.next = 3;
              return this.audioContext.resume();
            case 3:
              this.onStateChanged(true);
              this.log("Stream resumed...");
            case 5:
              this.isPaused = false;
            case 6:
            case "end":
              return _context7.stop();
          }
        }, _callee7, this);
      }));
      function ResumeStream() {
        return _ResumeStream.apply(this, arguments);
      }
      return ResumeStream;
    }()
  }, {
    key: "IsPaused",
    get: function get() {
      return this.isPaused;
    }
  }, {
    key: "StopStream",
    value: function () {
      var _StopStream = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee8() {
        return _regeneratorRuntime().wrap(function _callee8$(_context8) {
          while (1) switch (_context8.prev = _context8.next) {
            case 0:
              if (!(this.audioContext.state !== "suspended")) {
                _context8.next = 4;
                break;
              }
              _context8.next = 3;
              return this.audioContext.suspend();
            case 3:
              this.onStateChanged(false);
            case 4:
              this.log("Stream stopped...");
              // message sent to worklet-thread
              this.processorNode.port.postMessage(STOP_MSG);
            case 6:
            case "end":
              return _context8.stop();
          }
        }, _callee8, this);
      }));
      function StopStream() {
        return _StopStream.apply(this, arguments);
      }
      return StopStream;
    }()
  }, {
    key: "cleanup",
    value: function cleanup() {
      // Uncomment to stop recorded audio
      // this.source.stop();
      // Uncomment to stop microphone audio
      this.source.mediaStream.getAudioTracks()[0].stop();
      this.source.disconnect();
      this.processorNode.disconnect();
      this.processorNode.port.close();
      this.audioContext.close();
    }
  }, {
    key: "saveAudio",
    value: function saveAudio() {
      var wavView = this.encodeWAV();
      var url = URL.createObjectURL(new Blob([wavView], {
        type: "audio/wav"
      }));
      this.log("Download Recording: ".concat(url));
    }

    /**
     * Returns a Blob object containing the audio data in WAV format.
     * @returns {Blob} - Blob object containing the audio data in WAV format.
     */
  }, {
    key: "getBlob",
    value: function getBlob() {
      var wavView = this.encodeWAV();
      console.log(wavView);
      var audioBlob = new Blob([wavView], {
        type: "audio/wav"
      });
      console.log(audioBlob);
      return audioBlob;
    }

    // 16-bit PCM mono audio @ 16kHz
  }, {
    key: "encodeWAV",
    value: function encodeWAV() {
      // DataView to hold audio data, 2 bytes per int16
      var view = new DataView(new ArrayBuffer(this.audioData.length * 2));
      this.audioData.forEach(function (value, index) {
        view.setInt16(index * 2, value, true);
      });
      var dataLength = view.buffer.byteLength;
      var fileSize = 44 + dataLength;
      var wavView = new DataView(new ArrayBuffer(fileSize));

      // WAV header
      wavView.setUint32(0, 0x52494646, false); // "RIFF" in ASCII
      wavView.setUint32(4, fileSize - 8, true);
      wavView.setUint32(8, 0x57415645, false); // "WAVE" in ASCII
      wavView.setUint32(12, 0x666d7420, false); // "fmt " in ASCII
      wavView.setUint32(16, 16, true); // Size of the "fmt" chunk
      wavView.setUint16(20, 1, true); // Audio format (PCM)
      wavView.setUint16(22, CHANNEL_COUNT, true);
      wavView.setUint32(24, SAMPLE_RATE, true);
      wavView.setUint32(28, SAMPLE_RATE * CHANNEL_COUNT * (BITS_PER_SAMPLE / 8), true); // Byte rate
      wavView.setUint16(32, CHANNEL_COUNT * (BITS_PER_SAMPLE / 8), true);
      wavView.setUint16(34, BITS_PER_SAMPLE, true);
      wavView.setUint32(36, 0x64617461, false); // "data" in ASCII
      wavView.setUint32(40, dataLength, true);

      // Write the audio data to the WAV file
      for (var i = 0; i < dataLength; i++) {
        wavView.setInt8(44 + i, view.getInt8(i));
      }
      return wavView;
    }
  }, {
    key: "log",
    value: function log(event) {
      if (this.enableLogs) {
        var data = "".concat(new Date().toLocaleTimeString(), ": ").concat(event);
        console.log(data + "\n");
      }
    }
  }]);
}();

var AugnitoRecorder = /*#__PURE__*/function () {
  function AugnitoRecorder() {
    var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
      serverURL: "",
      enableLogs: false,
      isDebug: false,
      bufferInterval: 1,
      EOS_Message: undefined,
      socketTimeoutInterval: undefined
    };
    var heavyOp = arguments.length > 1 ? arguments[1] : undefined;
    _classCallCheck(this, AugnitoRecorder);
    this.WebsocketURL = config.serverURL !== "" ? config.serverURL : "";
    this.enableLogs = config.enableLogs;
    this.isDebug = config.isDebug;
    this.streamer = null;
    this.heavyOp = heavyOp;
    this.bufferInterval = config.bufferInterval;
    this.eosMessage = config.EOS_Message;
    this.socketTimeoutInterval = config.socketTimeoutInterval;
  }
  return _createClass(AugnitoRecorder, [{
    key: "togglePauseResumeAudioStream",
    value: function togglePauseResumeAudioStream() {
      if (!this.streamer) {
        this.startAudio();
      } else {
        if (this.streamer.IsPaused) {
          this.resumeAudio();
        } else {
          this.pauseAudio();
        }
      }
    }
  }, {
    key: "toggleStartStopAudioStream",
    value: function toggleStartStopAudioStream() {
      if (!this.streamer) {
        this.startAudio();
      } else {
        this.stopAudio();
      }
    }
  }, {
    key: "startAudio",
    value: function startAudio() {
      this.streamer = new Streamer(this.WebsocketURL, this.enableLogs, this.isDebug, this.bufferInterval, this.eosMessage, this.socketTimeoutInterval, this.heavyOp, this.onFinalResultCallback.bind(this), this.onPartialResultCallback.bind(this), this.onErrorCallback.bind(this), this.onStateChangedCallback.bind(this), this.onSessionEventCallback.bind(this), this.onOtherResultCallback.bind(this));
      this.streamer.StartStream();
      this.log("Stream Started...");
    }
  }, {
    key: "pauseAudio",
    value: function pauseAudio() {
      this.streamer.PauseStream();
      this.log("Stream Paused...");
    }
  }, {
    key: "resumeAudio",
    value: function resumeAudio() {
      this.streamer.ResumeStream();
      if (this.enableLogs) this.log("Stream Resumed...");
    }
  }, {
    key: "stopAudio",
    value: function stopAudio() {
      this.streamer.StopStream();
      this.streamer = null;
      this.log("Stream Stopped...");
    }
  }, {
    key: "getBlob",
    value: function getBlob() {
      var audioBlob = this.streamer.getBlob();
      this.log("Blob Sent...");
      return audioBlob;
    }
  }, {
    key: "log",
    value: function log(event) {
      if (this.enableLogs) {
        var data = "".concat(new Date().toLocaleTimeString(), ": ").concat(event);
        this.showLogCallback(data + "\n");
      }
    }

    // #endregion
    // #region client callbacks
  }, {
    key: "onSessionEventCallback",
    value: function onSessionEventCallback(data) {
      if (this.onSessionEvent) {
        this.onSessionEvent(data);
      }
    }
  }, {
    key: "onStateChangedCallback",
    value: function onStateChangedCallback(isRecording) {
      if (this.onStateChanged) {
        this.onStateChanged(isRecording);
      }
    }
  }, {
    key: "onErrorCallback",
    value: function onErrorCallback(errorMessage) {
      if (this.onError) {
        this.onError(errorMessage);
      }
    }
  }, {
    key: "onPartialResultCallback",
    value: function onPartialResultCallback(hype) {
      if (this.onPartialResult) {
        this.onPartialResult(hype);
      }
    }
  }, {
    key: "onFinalResultCallback",
    value: function onFinalResultCallback(recipe) {
      if (this.onFinalResult) {
        this.onFinalResult(recipe);
      }
    }
  }, {
    key: "onOtherResultCallback",
    value: function onOtherResultCallback(message) {
      if (this.onOtherResults) {
        this.onOtherResults(message);
      }
    }
  }, {
    key: "showLogCallback",
    value: function showLogCallback(event) {
      if (this.showLog) {
        this.showLog(event);
      }
    }
  }]);
}();

/**
 * Augnito Ambient Manager
 * @description Handles the connection with the Ambient API Server.
 */
class AugnitoAmbient {
    constructor(config) {
        this._logTag = "Augnito-Ambient";
        this._ambientRestAPI = new AmbientRestAPI(this.validateConfig(config));
        this.config = this.createSocketConfig(this.validateConfig(config));
    }
    initRecorder(_filetype, _noteparams) {
        var _a;
        console.log(_filetype, _noteparams);
        this.recorderIns = new AugnitoRecorder({
            // "{\"Region\": 801, \"Specialty\": 200, \"NoteType\": 40, \"Gender\": 0}"
            serverURL: ((_a = this.config) === null || _a === void 0 ? void 0 : _a.prepareWSSURL(_filetype, _noteparams)) || "",
            enableLogs: true,
            isDebug: false,
            bufferInterval: 30,
            EOS_Message: "AMBIENTSDKEOS",
            socketTimeoutInterval: 10000,
        });
        this.recorderIns.onError = this.onErrorCallback.bind(this);
        this.recorderIns.onStateChanged = this.onStateChangeCallback.bind(this);
        this.recorderIns.onSessionEvent =
            this.onSessionEventCallback.bind(this);
        this.recorderIns.onOtherResults =
            this.onOtherResultsCallback.bind(this);
    }
    // #region Public Methods
    /**
     * Returns the Note parameters which need be use while doing toggle listeing
     * @returns JSON object of Note parameters
     */
    getNoteParams() {
        return __awaiter(this, void 0, void 0, function* () {
            try {
                if (!this._ambientRestAPI) {
                    Logger_2.error("SDK not initialized", this._logTag);
                    return;
                }
                return yield this._ambientRestAPI.GetNoteParams();
            }
            catch (e) {
                if (e instanceof Error) {
                    this.onErrorCallback(e.message);
                }
            }
        });
    }
    /**
     * @param JobId to retrieve output for a specific audio file
     * @returns JSON object contains both Transcript and Note on sucess else fail resonse
     */
    getSummarizedNote(JobId) {
        return __awaiter(this, void 0, void 0, function* () {
            try {
                if (!this._ambientRestAPI) {
                    Logger_2.error("SDK not initialized", this._logTag);
                    return;
                }
                var responseJson = yield this._ambientRestAPI.FetchJob(JobId);
                if (responseJson) {
                    if (responseJson.Status === 200) {
                        return responseJson;
                    }
                    else {
                        this.onErrorCallback(responseJson.ErrorMessage);
                    }
                }
                else {
                    this.onErrorCallback("Unknown Error!");
                }
            }
            catch (e) {
                if (e instanceof Error) {
                    this.onErrorCallback(e.message);
                }
            }
        });
    }
    /**
     * @param JobId needs to pass to store the final Note for that audio
     * @param NoteDate This key will store the final edited Note that user wants to send.
     * @returns suceess response on successful submit of note else fail response
     */
    sendSummarizedNote(JobId, NoteDate) {
        return __awaiter(this, void 0, void 0, function* () {
            try {
                if (!this._ambientRestAPI) {
                    Logger_2.error("SDK not initialized", this._logTag);
                    return;
                }
                return yield this._ambientRestAPI.SendFinalNote(JobId, NoteDate);
            }
            catch (e) {
                if (e instanceof Error) {
                    this.onErrorCallback(e.message);
                }
            }
        });
    }
    /**
     * @param filetype Type of file being uploaded, wav, mp3, etc. Ex: “filetype=wav“
     * @param noteparams Qualifiers to determine the type of clinical note to be generated for that audio file.
     * @returns Callback triggers to reurn the Job id on meta message
     */
    toggleListening(_filetype, _noteparams) {
        var _a;
        console.log("toggleListening:", _filetype, _noteparams);
        if (!this.recorderIns) {
            this.initRecorder(_filetype, _noteparams);
        }
        (_a = this.recorderIns) === null || _a === void 0 ? void 0 : _a.toggleStartStopAudioStream();
    }
    // #endregion
    // #region client callbacks
    onEventCallback(data) {
        if (this.onJobCreated) {
            this.onJobCreated(data);
        }
    }
    onStateChangeCallback(isRecording) {
        if (this.onStateChanged) {
            this.onStateChanged(isRecording);
        }
    }
    onErrorCallback(errorMessage) {
        if (this.onError) {
            this.onError(errorMessage);
        }
    }
    onOtherResultsCallback(data) {
        if (this.onOtherResult) {
            this.onOtherResult(data);
        }
    }
    onIdleMicCallback() {
        if (this.onIdleMic) {
            this.onIdleMic();
        }
    }
    onSessionEventCallback(data) {
        var _a;
        if (!data) {
            return;
        }
        let json;
        try {
            json = typeof data === "string" ? JSON.parse(data) : data;
        }
        catch (error) {
            Logger_2.error(`Error parsing session event data: ${error}`, this._logTag);
            return;
        }
        if (!json || !("Type" in json)) {
            return;
        }
        if (json.Type.toLowerCase() === "meta" && ((_a = this.config) === null || _a === void 0 ? void 0 : _a.onMetaEvent)) {
            if (!json.JobID) {
                Logger_2.error(`JobID is missing in meta event`, this._logTag);
                return;
            }
            this.config.onMetaEvent(json.JobID);
        }
        else if (json.Type.toLowerCase() === "error" && json.Data) {
            this.onErrorCallback(json.Data);
        }
        if (typeof json.Event !== "object" || json.Event === null) {
            return;
        }
        const { Type: eventType, Value: eventValue } = json.Event;
        if (!eventType) {
            return;
        }
        if (eventType === "SESSION_CREATED" && eventValue) {
            Logger_2.log(`session Token ${eventValue}`, this._logTag);
        }
        else if (eventType === "SERVICE_DOWN") {
            Logger_2.error(eventType, this._logTag);
        }
        else if (eventType === "NO_DICTATION_STOP_MIC") {
            Logger_2.log("NO_DICTATION_STOP_MIC", this._logTag);
            this.onIdleMicCallback();
        }
        else if (eventType === "INVALID_AUTH_CREDENTIALS") {
            Logger_2.error("INVALID_AUTH_CREDENTIALS", this._logTag);
        }
        else if (eventType === "LOW_BANDWIDTH") {
            Logger_2.log("LOW_BANDWIDTH: Check internet connection", this._logTag);
        }
    }
    // #endregion
    /**
     * Validates the Ambient config has all the mandatory fields
     * @param config The config sent by the client application
     */
    validateConfig(config) {
        Guard_2.Against.NullOrEmpty(config.server, "Server");
        Guard_2.Against.NullOrEmpty(config.subscriptionCode, "SubscriptionCode");
        Guard_2.Against.NullOrEmpty(config.accessKey, "AccessKey");
        Guard_2.Against.NullOrEmpty(config.userTag, "UserTag");
        return config;
    }
    createSocketConfig(config) {
        const _socketConfig = new socketConfig(config);
        // _socketConfig.onStartOfRecording =
        //     this.onStateChangeCallback.bind(this);
        // _socketConfig.onStopOfRecording = this.onStateChangeCallback.bind(this);
        _socketConfig.onError = this.onErrorCallback.bind(this);
        _socketConfig.onMetaEvent = this.onEventCallback.bind(this);
        return _socketConfig;
    }
}

export { AugnitoAmbient };
//# sourceMappingURL=augnitoambientsdk.js.map