uneeq-js 2.46.0 → 2.46.2

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.
@@ -0,0 +1,9 @@
1
+ export declare class UneeqLocalStorage {
2
+ private localStorageAvailable?;
3
+ constructor();
4
+ get available(): boolean;
5
+ setItemSafely(key: string, value: string): void;
6
+ getItemSafely(key: string): any;
7
+ removeItemSafely(key: string): void;
8
+ private checkIfLocalStorageAvailable;
9
+ }
@@ -16,6 +16,7 @@ export declare enum UneeqMessageType {
16
16
  AvatarAvailable = "AvatarAvailable",
17
17
  AvatarUnavailable = "AvatarUnavailable",
18
18
  ConnectionLost = "ConnectionLost",
19
+ ResumeSessionUnavailable = "ResumeSessionUnavailable",
19
20
  ServiceUnavailable = "ServiceUnavailable",
20
21
  OnlineStatusUpdate = "OnlineStatusUpdate",
21
22
  MicActivityNotSupported = "MicActivityNotSupported",
@@ -190,6 +191,13 @@ export declare class ConnectionLostMessage implements UneeqMessage {
190
191
  uneeqMessageType: UneeqMessageType;
191
192
  constructor(connectionState: PublishSubscribeState);
192
193
  }
194
+ /**
195
+ * Resume Session Unavailable
196
+ */
197
+ export declare class ResumeSessionUnavailable implements UneeqMessage {
198
+ uneeqMessageType: UneeqMessageType;
199
+ constructor();
200
+ }
193
201
  /**
194
202
  * The avatar's answer to a question
195
203
  */
@@ -32,6 +32,7 @@ export declare class Uneeq {
32
32
  private streamManager;
33
33
  private digitalHumanVideoElement;
34
34
  private sessionWasResumed;
35
+ private uneeqLocalStorage;
35
36
  constructor(options: UneeqOptions);
36
37
  setLoggerEnabled(enabled: boolean): void;
37
38
  /**
@@ -151,4 +152,9 @@ export declare class Uneeq {
151
152
  */
152
153
  private initOnlineStatusUpdateMessages;
153
154
  private initPromMetricsListener;
155
+ /**
156
+ * Check if resume session functionality is available (localStorage is available)
157
+ * Warn implementer if unavailable
158
+ */
159
+ private checkIfResumeSessionIsAvailable;
154
160
  }
package/dist/umd/index.js CHANGED
@@ -5764,12 +5764,13 @@ const online_status_service_1 = __webpack_require__(305);
5764
5764
  const prom_1 = __webpack_require__(270);
5765
5765
  const resume_session_check_1 = __webpack_require__(306);
5766
5766
  const stream_manager_1 = __webpack_require__(307);
5767
- const voice_input_manager_1 = __webpack_require__(308);
5767
+ const uneeq_local_storage_1 = __webpack_require__(308);
5768
+ const voice_input_manager_1 = __webpack_require__(309);
5768
5769
  const MessageTypes_1 = __webpack_require__(267);
5769
- const NewSessionRequest_1 = __webpack_require__(311);
5770
+ const NewSessionRequest_1 = __webpack_require__(312);
5770
5771
  const PublishSubscribeState_1 = __webpack_require__(231);
5771
- const SourceApp_1 = __webpack_require__(312);
5772
- const VoiceInputMode_1 = __webpack_require__(310);
5772
+ const SourceApp_1 = __webpack_require__(313);
5773
+ const VoiceInputMode_1 = __webpack_require__(311);
5773
5774
  class Uneeq {
5774
5775
  constructor(options) {
5775
5776
  this.ready = new rxjs_1.BehaviorSubject(false);
@@ -5780,6 +5781,7 @@ class Uneeq {
5780
5781
  this.sessionStarted = false; /* Whether the user is live in a session with an avatar (different from sessionPaused) */
5781
5782
  this.unavailableAvatarMsgSent = false;
5782
5783
  this.sessionWasResumed = false;
5784
+ this.uneeqLocalStorage = new uneeq_local_storage_1.UneeqLocalStorage();
5783
5785
  logger_1.logger.enabled = options.logging || false;
5784
5786
  this.options = options;
5785
5787
  this.options.diagnostics = options.diagnostics || false;
@@ -5791,6 +5793,7 @@ class Uneeq {
5791
5793
  this.options.backgroundImageUrl = options.backgroundImageUrl || '';
5792
5794
  this.options.nameTagImageUrl = options.nameTagImageUrl || '';
5793
5795
  this.options.speechToTextLocales = locale_detector_1.LocaleDetector.validateOrDetectSpeechLocales(options);
5796
+ this.checkIfResumeSessionIsAvailable();
5794
5797
  // TODO update default mode to VOICE_ACTIVITY once we are confident in the solution.
5795
5798
  this.options.voiceInputMode = options.voiceInputMode || VoiceInputMode_1.VoiceInputMode.PUSH_TO_TALK;
5796
5799
  this.api = new api_1.API(this.options.url, this.options.apiKey);
@@ -5860,8 +5863,8 @@ class Uneeq {
5860
5863
  logger_1.logger.log('UneeQ: Session was not resumed.');
5861
5864
  }
5862
5865
  // put the session id and persona id into local storage so it can be resumed
5863
- localStorage.setItem('uneeqResumeSessionId', this.session.id);
5864
- localStorage.setItem('uneeqResumeSessionPersonaId', this.options.conversationId);
5866
+ this.uneeqLocalStorage.setItemSafely('uneeqResumeSessionId', this.session.id);
5867
+ this.uneeqLocalStorage.setItemSafely('uneeqResumeSessionPersonaId', this.options.conversationId);
5865
5868
  this.session.sourceApp = SourceApp_1.SourceApp[this.session.sourceApp ? this.session.sourceApp : ''] ?
5866
5869
  this.session.sourceApp : SourceApp_1.SourceApp.UNKNOWN;
5867
5870
  this.initialize();
@@ -6180,7 +6183,7 @@ class Uneeq {
6180
6183
  speechToTextLocales: this.options.speechToTextLocales
6181
6184
  }).catch((err) => {
6182
6185
  console.error('UneeQ: Digital human could not be started. Clearing resumeSession token and ending process.', err);
6183
- localStorage.removeItem('uneeqResumeSessionId');
6186
+ this.uneeqLocalStorage.removeItemSafely('uneeqResumeSessionId');
6184
6187
  });
6185
6188
  }
6186
6189
  else {
@@ -6255,6 +6258,17 @@ class Uneeq {
6255
6258
  prom.handleMessage(message.promMsg);
6256
6259
  });
6257
6260
  }
6261
+ /**
6262
+ * Check if resume session functionality is available (localStorage is available)
6263
+ * Warn implementer if unavailable
6264
+ */
6265
+ checkIfResumeSessionIsAvailable() {
6266
+ if (this.options.resumeSession === true && !this.uneeqLocalStorage.available) {
6267
+ console.warn('UneeQ: Resuming session is unavailable in this browser because localStorage is not allowed.');
6268
+ this.messages.next(new MessageTypes_1.ResumeSessionUnavailable());
6269
+ this.options.resumeSession = false;
6270
+ }
6271
+ }
6258
6272
  }
6259
6273
  exports.Uneeq = Uneeq;
6260
6274
 
@@ -18159,7 +18173,7 @@ function zipAll(project) {
18159
18173
  /* 224 */
18160
18174
  /***/ (function(module) {
18161
18175
 
18162
- module.exports = JSON.parse("{\"name\":\"uneeq-js\",\"version\":\"2.46.0\",\"description\":\"\",\"main\":\"dist/index.js\",\"types\":\"dist/src/index.d.ts\",\"scripts\":{\"start\":\"npx webpack -w\",\"test-local\":\"npx karma start karma.conf.js -logLevel=DEBUG\",\"test\":\"npx karma start --browsers ChromeHeadless --single-run\",\"test:windows\":\"karma start karma.conf.js\",\"build\":\"webpack --config webpack.config.prod.js && webpack --config webpack.config.umd.js\",\"lint\":\"npx tslint -p tsconfig.json --fix\",\"docs\":\"npx typedoc --options\"},\"files\":[\"dist\",\"!dist/test\"],\"author\":\"\",\"license\":\"ISC\",\"dependencies\":{\"@stomp/stompjs\":\"^6.0.0\",\"@uehreka/seriously\":\"^1.0.1\",\"fast-text-encoding\":\"^1.0.0\",\"intrinsic-scale\":\"^3.0.4\",\"promjs\":\"^0.4.1\",\"rxjs\":\"^6.2.2\",\"rxjs-compat\":\"^6.3.2\",\"simple-peer\":\"9.11.0\",\"webrtc-adapter\":\"8.1.0\"},\"devDependencies\":{\"@types/jasmine\":\"^2.8.8\",\"@types/node\":\"^10.9.4\",\"fetch-mock\":\"7.7.3\",\"ignore-styles\":\"^5.0.1\",\"jasmine\":\"^3.2.0\",\"jasmine-class-mock\":\"^1.0.1\",\"jasmine-core\":\"^3.3.0\",\"karma\":\"^5.0.0\",\"karma-chrome-launcher\":\"^2.2.0\",\"karma-firefox-launcher\":\"^1.1.0\",\"karma-jasmine\":\"^2.0.1\",\"karma-jasmine-html-reporter\":\"^1.4.0\",\"karma-requirejs\":\"^1.1.0\",\"karma-safari-launcher\":\"^1.0.0\",\"karma-typescript\":\"^5.0.0\",\"karma-typescript-es6-transform\":\"^5.0.0\",\"nock\":\"^9.6.1\",\"requirejs\":\"^2.3.6\",\"ts-loader\":\"^5.0.0\",\"ts-node\":\"^7.0.1\",\"tslint\":\"^5.11.0\",\"tslint-no-focused-test\":\"^0.5.0\",\"typedoc\":\"^0.18.0\",\"typescript\":\"^3.9.7\",\"webpack\":\"^4.17.1\",\"webpack-cli\":\"^3.1.0\"}}");
18176
+ module.exports = JSON.parse("{\"name\":\"uneeq-js\",\"version\":\"2.46.2\",\"description\":\"\",\"main\":\"dist/index.js\",\"types\":\"dist/src/index.d.ts\",\"scripts\":{\"start\":\"npx webpack -w\",\"test-local\":\"npx karma start karma.conf.js -logLevel=DEBUG\",\"test\":\"npx karma start --browsers ChromeHeadless --single-run\",\"test:windows\":\"karma start karma.conf.js\",\"build\":\"webpack --config webpack.config.prod.js && webpack --config webpack.config.umd.js\",\"lint\":\"npx tslint -p tsconfig.json --fix\",\"docs\":\"npx typedoc --options\"},\"files\":[\"dist\",\"!dist/test\"],\"author\":\"\",\"license\":\"ISC\",\"dependencies\":{\"@stomp/stompjs\":\"^6.0.0\",\"@uehreka/seriously\":\"^1.0.1\",\"fast-text-encoding\":\"^1.0.0\",\"intrinsic-scale\":\"^3.0.4\",\"promjs\":\"^0.4.1\",\"rxjs\":\"^6.2.2\",\"rxjs-compat\":\"^6.3.2\",\"simple-peer\":\"9.11.0\",\"webrtc-adapter\":\"8.1.0\"},\"devDependencies\":{\"@types/jasmine\":\"^2.8.8\",\"@types/node\":\"^10.9.4\",\"fetch-mock\":\"7.7.3\",\"ignore-styles\":\"^5.0.1\",\"jasmine\":\"^3.2.0\",\"jasmine-class-mock\":\"^1.0.1\",\"jasmine-core\":\"^3.3.0\",\"karma\":\"^5.0.0\",\"karma-chrome-launcher\":\"^2.2.0\",\"karma-firefox-launcher\":\"^1.1.0\",\"karma-jasmine\":\"^2.0.1\",\"karma-jasmine-html-reporter\":\"^1.4.0\",\"karma-requirejs\":\"^1.1.0\",\"karma-safari-launcher\":\"^1.0.0\",\"karma-typescript\":\"^5.0.0\",\"karma-typescript-es6-transform\":\"^5.0.0\",\"nock\":\"^9.6.1\",\"requirejs\":\"^2.3.6\",\"ts-loader\":\"^5.0.0\",\"ts-node\":\"^7.0.1\",\"tslint\":\"^5.11.0\",\"tslint-no-focused-test\":\"^0.5.0\",\"typedoc\":\"^0.18.0\",\"typescript\":\"^3.9.7\",\"webpack\":\"^4.17.1\",\"webpack-cli\":\"^3.1.0\"}}");
18163
18177
 
18164
18178
  /***/ }),
18165
18179
  /* 225 */
@@ -32428,7 +32442,7 @@ exports.DigitalHumanVideoPlayManager = DigitalHumanVideoPlayManager;
32428
32442
  "use strict";
32429
32443
 
32430
32444
  Object.defineProperty(exports, "__esModule", { value: true });
32431
- exports.DigitalHumanUnmuted = exports.DigitalHumanPlayedInMutedModeSuccess = exports.DigitalHumanFailedToPlay = exports.DigitalHumanVideoError = exports.ClientPerformanceMessage = exports.ClientMediaStreamUpdateMessage = exports.OnlineStatusUpdateMessage = exports.SessionInfoMessage = exports.AvatarRequestIgnored = exports.AvatarRequestCompleted = exports.SessionErrorMessage = exports.WebRtcStatsMessage = exports.WebRtcDataMessage = exports.SessionLiveMessage = exports.WarningMessage = exports.RecordingStoppedMessage = exports.RecordingStartedMessage = exports.DevicePermissionAllowedMessage = exports.AvatarTextInputFinishedMessage = exports.FinishedSpeakingMessage = exports.StartedSpeakingMessage = exports.AvatarQuestionMessage = exports.InstructionsMessage = exports.AvatarAnswerContentMessage = exports.AvatarAnswerMessage = exports.ConnectionLostMessage = exports.VoiceActivityInputModeNotSupportedMessage = exports.MicActivityNotSupportedMessage = exports.MicActivityMessage = exports.MicActivityErrorMessage = exports.ServiceUnavailableMessage = exports.AvatarUnavailableMessage = exports.AvatarAvailableMessage = exports.SessionEndedMessage = exports.SessionResumedMessage = exports.SessionPausedMessage = exports.DeviceListUpdatedMessage = exports.DeviceErrorMessage = exports.SetSpeakerSuccessMessage = exports.SetMicSuccessMessage = exports.SetCameraSuccessMessage = exports.DeviceNotFoundErrorMessage = exports.ReadyMessage = exports.UneeqMessageType = void 0;
32445
+ exports.DigitalHumanUnmuted = exports.DigitalHumanPlayedInMutedModeSuccess = exports.DigitalHumanFailedToPlay = exports.DigitalHumanVideoError = exports.ClientPerformanceMessage = exports.ClientMediaStreamUpdateMessage = exports.OnlineStatusUpdateMessage = exports.SessionInfoMessage = exports.AvatarRequestIgnored = exports.AvatarRequestCompleted = exports.SessionErrorMessage = exports.WebRtcStatsMessage = exports.WebRtcDataMessage = exports.SessionLiveMessage = exports.WarningMessage = exports.RecordingStoppedMessage = exports.RecordingStartedMessage = exports.DevicePermissionAllowedMessage = exports.AvatarTextInputFinishedMessage = exports.FinishedSpeakingMessage = exports.StartedSpeakingMessage = exports.AvatarQuestionMessage = exports.InstructionsMessage = exports.AvatarAnswerContentMessage = exports.AvatarAnswerMessage = exports.ResumeSessionUnavailable = exports.ConnectionLostMessage = exports.VoiceActivityInputModeNotSupportedMessage = exports.MicActivityNotSupportedMessage = exports.MicActivityMessage = exports.MicActivityErrorMessage = exports.ServiceUnavailableMessage = exports.AvatarUnavailableMessage = exports.AvatarAvailableMessage = exports.SessionEndedMessage = exports.SessionResumedMessage = exports.SessionPausedMessage = exports.DeviceListUpdatedMessage = exports.DeviceErrorMessage = exports.SetSpeakerSuccessMessage = exports.SetMicSuccessMessage = exports.SetCameraSuccessMessage = exports.DeviceNotFoundErrorMessage = exports.ReadyMessage = exports.UneeqMessageType = void 0;
32432
32446
  var UneeqMessageType;
32433
32447
  (function (UneeqMessageType) {
32434
32448
  UneeqMessageType["Ready"] = "Ready";
@@ -32442,6 +32456,7 @@ var UneeqMessageType;
32442
32456
  UneeqMessageType["AvatarAvailable"] = "AvatarAvailable";
32443
32457
  UneeqMessageType["AvatarUnavailable"] = "AvatarUnavailable";
32444
32458
  UneeqMessageType["ConnectionLost"] = "ConnectionLost";
32459
+ UneeqMessageType["ResumeSessionUnavailable"] = "ResumeSessionUnavailable";
32445
32460
  UneeqMessageType["ServiceUnavailable"] = "ServiceUnavailable";
32446
32461
  UneeqMessageType["OnlineStatusUpdate"] = "OnlineStatusUpdate";
32447
32462
  UneeqMessageType["MicActivityNotSupported"] = "MicActivityNotSupported";
@@ -32652,6 +32667,15 @@ class ConnectionLostMessage {
32652
32667
  }
32653
32668
  }
32654
32669
  exports.ConnectionLostMessage = ConnectionLostMessage;
32670
+ /**
32671
+ * Resume Session Unavailable
32672
+ */
32673
+ class ResumeSessionUnavailable {
32674
+ constructor() {
32675
+ this.uneeqMessageType = UneeqMessageType.ResumeSessionUnavailable;
32676
+ }
32677
+ }
32678
+ exports.ResumeSessionUnavailable = ResumeSessionUnavailable;
32655
32679
  /**
32656
32680
  * The avatar's answer to a question
32657
32681
  */
@@ -32932,12 +32956,15 @@ class LocaleDetector {
32932
32956
  * @returns a colon separated string of locales (language tags)
32933
32957
  */
32934
32958
  static validateOrDetectSpeechLocales(options) {
32935
- const localeOptions = options.speechToTextLocales;
32936
- if (localeOptions && localeOptions.length > 0) {
32937
- if (!localeOptions.match(this.localesRegEx)) {
32938
- console.warn(`UneeQ: Potentially invalid value for speechToTextLocales: ${localeOptions}. Please use a BCP-47 language tag with multiple locales separated by colon .e.g 'en-US:ja-JP`);
32959
+ let speechToTextLocales = options.speechToTextLocales;
32960
+ // validate config language locales match regex and are not null or undefined
32961
+ if (speechToTextLocales && speechToTextLocales.length > 0) {
32962
+ if (!speechToTextLocales.match(this.localesRegEx)) {
32963
+ console.error(`UneeQ: Likely invalid value for speechToTextLocales: ${speechToTextLocales}. Please use a BCP-47 language tag with multiple locales separated by colon .e.g 'en-US:ja-JP`);
32964
+ }
32965
+ if (speechToTextLocales === 'undefined' || speechToTextLocales === 'null') {
32966
+ speechToTextLocales = this.defaultLocale;
32939
32967
  }
32940
- return localeOptions;
32941
32968
  }
32942
32969
  // Get the user's language preferences from the browser
32943
32970
  const userLanguages = window.navigator.languages || [window.navigator.language];
@@ -32956,8 +32983,8 @@ class LocaleDetector {
32956
32983
  // If the user's language preferences are empty, default to en-US
32957
32984
  userLanguageLocales = this.defaultLocale;
32958
32985
  }
32959
- // Return the concatenated language locales string
32960
- return userLanguageLocales;
32986
+ // Return the concatenated language locales string if config has not supplied any
32987
+ return speechToTextLocales || userLanguageLocales;
32961
32988
  }
32962
32989
  }
32963
32990
  exports.LocaleDetector = LocaleDetector;
@@ -53545,12 +53572,70 @@ exports.StreamManager = StreamManager;
53545
53572
 
53546
53573
  "use strict";
53547
53574
 
53575
+ Object.defineProperty(exports, "__esModule", { value: true });
53576
+ exports.UneeqLocalStorage = void 0;
53577
+ const logger_1 = __webpack_require__(233);
53578
+ class UneeqLocalStorage {
53579
+ constructor() { }
53580
+ get available() {
53581
+ if (this.localStorageAvailable === undefined) {
53582
+ this.localStorageAvailable = this.checkIfLocalStorageAvailable();
53583
+ }
53584
+ return this.localStorageAvailable;
53585
+ }
53586
+ setItemSafely(key, value) {
53587
+ if (this.available) {
53588
+ localStorage.setItem(key, value);
53589
+ }
53590
+ else {
53591
+ logger_1.logger.log('UneeQ: unable to access localStorage because it is not available.');
53592
+ }
53593
+ }
53594
+ getItemSafely(key) {
53595
+ if (this.available) {
53596
+ return localStorage.getItem(key);
53597
+ }
53598
+ else {
53599
+ logger_1.logger.log('UneeQ: unable to access localStorage because it is not available.');
53600
+ return undefined;
53601
+ }
53602
+ }
53603
+ removeItemSafely(key) {
53604
+ if (this.available) {
53605
+ localStorage.removeItem(key);
53606
+ }
53607
+ else {
53608
+ logger_1.logger.log('UneeQ: unable to access localStorage because it is not available.');
53609
+ }
53610
+ }
53611
+ checkIfLocalStorageAvailable() {
53612
+ const uneeqLocalStoreCheck = 'UneeqLocalStoreCheck';
53613
+ try {
53614
+ localStorage.setItem(uneeqLocalStoreCheck, uneeqLocalStoreCheck);
53615
+ localStorage.removeItem(uneeqLocalStoreCheck);
53616
+ return true;
53617
+ }
53618
+ catch (e) {
53619
+ console.warn('UneeQ: Local storage is not available. Reason: ', e);
53620
+ return false;
53621
+ }
53622
+ }
53623
+ }
53624
+ exports.UneeqLocalStorage = UneeqLocalStorage;
53625
+
53626
+
53627
+ /***/ }),
53628
+ /* 309 */
53629
+ /***/ (function(module, exports, __webpack_require__) {
53630
+
53631
+ "use strict";
53632
+
53548
53633
  Object.defineProperty(exports, "__esModule", { value: true });
53549
53634
  exports.VoiceInputManager = void 0;
53550
53635
  const operators_1 = __webpack_require__(126);
53551
- const soundmeter_1 = __webpack_require__(309);
53636
+ const soundmeter_1 = __webpack_require__(310);
53552
53637
  const MessageTypes_1 = __webpack_require__(267);
53553
- const VoiceInputMode_1 = __webpack_require__(310);
53638
+ const VoiceInputMode_1 = __webpack_require__(311);
53554
53639
  const logger_1 = __webpack_require__(233);
53555
53640
  class VoiceInputManager {
53556
53641
  constructor(options, api, messages, enableMicrophone) {
@@ -53717,7 +53802,7 @@ exports.VoiceInputManager = VoiceInputManager;
53717
53802
 
53718
53803
 
53719
53804
  /***/ }),
53720
- /* 309 */
53805
+ /* 310 */
53721
53806
  /***/ (function(module, exports, __webpack_require__) {
53722
53807
 
53723
53808
  "use strict";
@@ -53796,7 +53881,7 @@ exports.SoundMeter = SoundMeter;
53796
53881
 
53797
53882
 
53798
53883
  /***/ }),
53799
- /* 310 */
53884
+ /* 311 */
53800
53885
  /***/ (function(module, exports, __webpack_require__) {
53801
53886
 
53802
53887
  "use strict";
@@ -53811,7 +53896,7 @@ var VoiceInputMode;
53811
53896
 
53812
53897
 
53813
53898
  /***/ }),
53814
- /* 311 */
53899
+ /* 312 */
53815
53900
  /***/ (function(module, exports, __webpack_require__) {
53816
53901
 
53817
53902
  "use strict";
@@ -53825,7 +53910,7 @@ var SessionType;
53825
53910
 
53826
53911
 
53827
53912
  /***/ }),
53828
- /* 312 */
53913
+ /* 313 */
53829
53914
  /***/ (function(module, exports, __webpack_require__) {
53830
53915
 
53831
53916
  "use strict";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uneeq-js",
3
- "version": "2.46.0",
3
+ "version": "2.46.2",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/src/index.d.ts",
package/readme.md CHANGED
@@ -8,6 +8,12 @@ https://docs.uneeq.io/build-your-own-experience
8
8
  To use uneeq-js with a typescript version < 3.8, 'skipLibCheck' must be set to true.
9
9
 
10
10
  ## Release Notes
11
+ #### 2.46.2
12
+ * Fix for session starting in incognito browser windows.
13
+
14
+ #### 2.46.1
15
+ * Tweaking locale detection to better handle null or undefined input
16
+
11
17
  #### 2.46.0
12
18
  * Adding automatic detection of speech to text language - If no speechToTextLocales set, we will try to automatically detect a users browser language. If we cannot do that, we will fall back to en-US as the default speech to text language.
13
19