obi-sdk 0.3.13 → 0.4.1
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/README.md +25 -0
- package/dist/loader.d.ts +5 -2
- package/dist/modular/chunks/{obi-widget-d7e7c6bf.js → obi-widget-58dc98b0.js} +109 -47
- package/dist/modular/chunks/obi-widget-58dc98b0.js.map +1 -0
- package/dist/modular/chunks/{types-82772f00.js → types-e0297e7b.js} +2 -2
- package/dist/modular/chunks/{types-82772f00.js.map → types-e0297e7b.js.map} +1 -1
- package/dist/modular/core.js +1 -1
- package/dist/modular/index.js +95 -14
- package/dist/modular/index.js.map +1 -1
- package/dist/modular/ui.js +11 -11
- package/dist/obi-sdk.es.js +207 -64
- package/dist/obi-sdk.es.js.map +1 -1
- package/dist/obi-sdk.standalone.iife.js +51 -59
- package/dist/obi-sdk.standalone.iife.js.map +1 -1
- package/dist/obi-sdk.umd.js +40 -48
- package/dist/obi-sdk.umd.js.map +1 -1
- package/dist/ui/components/obi-widget.d.ts +3 -1
- package/dist/ui/components/session-start-modal.d.ts +0 -1
- package/index.d.ts +0 -2
- package/package.json +4 -4
- package/dist/modular/chunks/obi-widget-d7e7c6bf.js.map +0 -1
package/dist/obi-sdk.es.js
CHANGED
|
@@ -15466,23 +15466,23 @@ class RTCEngine extends eventsExports.EventEmitter {
|
|
|
15466
15466
|
this.close();
|
|
15467
15467
|
};
|
|
15468
15468
|
const duration2 = Date.now() - this.reconnectStart;
|
|
15469
|
-
let
|
|
15469
|
+
let delay2 = this.getNextRetryDelay({
|
|
15470
15470
|
elapsedMs: duration2,
|
|
15471
15471
|
retryCount: this.reconnectAttempts
|
|
15472
15472
|
});
|
|
15473
|
-
if (
|
|
15473
|
+
if (delay2 === null) {
|
|
15474
15474
|
disconnect(duration2);
|
|
15475
15475
|
return;
|
|
15476
15476
|
}
|
|
15477
15477
|
if (connection === leaveReconnect) {
|
|
15478
|
-
|
|
15478
|
+
delay2 = 0;
|
|
15479
15479
|
}
|
|
15480
|
-
this.log.debug("reconnecting in ".concat(
|
|
15480
|
+
this.log.debug("reconnecting in ".concat(delay2, "ms"), this.logContext);
|
|
15481
15481
|
this.clearReconnectTimeout();
|
|
15482
15482
|
if (this.token && this.regionUrlProvider) {
|
|
15483
15483
|
this.regionUrlProvider.updateToken(this.token);
|
|
15484
15484
|
}
|
|
15485
|
-
this.reconnectTimeout = CriticalTimers.setTimeout(() => this.attemptReconnect(disconnectReason).finally(() => this.reconnectTimeout = void 0),
|
|
15485
|
+
this.reconnectTimeout = CriticalTimers.setTimeout(() => this.attemptReconnect(disconnectReason).finally(() => this.reconnectTimeout = void 0), delay2);
|
|
15486
15486
|
};
|
|
15487
15487
|
this.waitForRestarted = () => {
|
|
15488
15488
|
return new Promise((resolve, reject) => {
|
|
@@ -22954,6 +22954,9 @@ class ObiSession {
|
|
|
22954
22954
|
this._userAudioTimer = null;
|
|
22955
22955
|
this.sessionId = sessionId;
|
|
22956
22956
|
this.apiBaseUrl = apiBaseUrl || DEFAULT_API_BASE_URL;
|
|
22957
|
+
this.client = new ObiClient({
|
|
22958
|
+
baseUrl: this.apiBaseUrl
|
|
22959
|
+
});
|
|
22957
22960
|
this.emitter = new EventEmitter();
|
|
22958
22961
|
}
|
|
22959
22962
|
emit(event, data) {
|
|
@@ -23010,7 +23013,7 @@ class ObiSession {
|
|
|
23010
23013
|
if (this.currentState === SDKState.RESEARCHING || this.currentState === SDKState.PAUSED)
|
|
23011
23014
|
return;
|
|
23012
23015
|
const state = attributes["lk.agent.state"];
|
|
23013
|
-
const newState = z$2(state).with("listening", () => SDKState.USER_SPEAKING).with("speaking", () => SDKState.AGENT_SPEAKING).with("thinking", () => SDKState.
|
|
23016
|
+
const newState = z$2(state).with("listening", () => SDKState.USER_SPEAKING).with("speaking", () => SDKState.AGENT_SPEAKING).with("thinking", () => SDKState.THINKING).otherwise(() => void 0);
|
|
23014
23017
|
if (!newState)
|
|
23015
23018
|
return;
|
|
23016
23019
|
this.setState(newState);
|
|
@@ -23080,10 +23083,8 @@ class ObiSession {
|
|
|
23080
23083
|
dynacast: true
|
|
23081
23084
|
});
|
|
23082
23085
|
this.setupRoomEventListeners();
|
|
23083
|
-
const
|
|
23084
|
-
|
|
23085
|
-
const joinToken = await fetch(joinEndpoint).then((res) => res.json());
|
|
23086
|
-
await this.room.connect(joinToken.url, joinToken.token);
|
|
23086
|
+
const joinToken = await this.client.getJoinToken(this.sessionId, { skipIntro: true });
|
|
23087
|
+
await this.room.connect(joinToken.data.url, joinToken.data.token);
|
|
23087
23088
|
if (this.microphoneStream) {
|
|
23088
23089
|
const micTrack = this.microphoneStream.getAudioTracks()[0];
|
|
23089
23090
|
await this.room.localParticipant.publishTrack(micTrack, {
|
|
@@ -23092,8 +23093,8 @@ class ObiSession {
|
|
|
23092
23093
|
});
|
|
23093
23094
|
}
|
|
23094
23095
|
return {
|
|
23095
|
-
url: joinToken.url,
|
|
23096
|
-
token: joinToken.token
|
|
23096
|
+
url: joinToken.data.url,
|
|
23097
|
+
token: joinToken.data.token
|
|
23097
23098
|
};
|
|
23098
23099
|
} catch (error) {
|
|
23099
23100
|
console.error("Failed to connect to LiveKit:", error);
|
|
@@ -23138,6 +23139,9 @@ class ObiSession {
|
|
|
23138
23139
|
this.currentState = newState;
|
|
23139
23140
|
this.emitter.emit("stateChanged", newState);
|
|
23140
23141
|
}
|
|
23142
|
+
getCurrentState() {
|
|
23143
|
+
return this.currentState;
|
|
23144
|
+
}
|
|
23141
23145
|
async requestMicrophone() {
|
|
23142
23146
|
try {
|
|
23143
23147
|
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
@@ -23294,7 +23298,6 @@ class ObiSession {
|
|
|
23294
23298
|
}
|
|
23295
23299
|
}
|
|
23296
23300
|
const SESSION_URL_PARAM = "49206C6F7665204F6269_session";
|
|
23297
|
-
const API_KEY_URL_PARAM = "49206C6F7665204F6269_client";
|
|
23298
23301
|
var extendStatics = function(d2, b2) {
|
|
23299
23302
|
extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d3, b3) {
|
|
23300
23303
|
d3.__proto__ = b3;
|
|
@@ -33389,7 +33392,7 @@ class DotLoader extends LitElement {
|
|
|
33389
33392
|
animateSequence() {
|
|
33390
33393
|
this.activeDots = Array(this.numDots).fill(false);
|
|
33391
33394
|
for (let i2 = 0; i2 < this.numDots; i2++) {
|
|
33392
|
-
const
|
|
33395
|
+
const delay2 = i2 * (this.animationDuration * this.overlapFactor);
|
|
33393
33396
|
const bounceStartId = window.setTimeout(() => {
|
|
33394
33397
|
this.activeDots = [...this.activeDots];
|
|
33395
33398
|
this.activeDots[i2] = true;
|
|
@@ -33398,7 +33401,7 @@ class DotLoader extends LitElement {
|
|
|
33398
33401
|
this.activeDots[i2] = false;
|
|
33399
33402
|
}, this.animationDuration);
|
|
33400
33403
|
this.timeoutIds.push(bounceEndId);
|
|
33401
|
-
},
|
|
33404
|
+
}, delay2);
|
|
33402
33405
|
this.timeoutIds.push(bounceStartId);
|
|
33403
33406
|
}
|
|
33404
33407
|
const nextSequenceId = window.setTimeout(
|
|
@@ -33507,14 +33510,9 @@ class SessionStartModal extends LitElement {
|
|
|
33507
33510
|
this.onClose();
|
|
33508
33511
|
}
|
|
33509
33512
|
}
|
|
33510
|
-
handleBackdropClick(e2) {
|
|
33511
|
-
if (e2.target === e2.currentTarget) {
|
|
33512
|
-
this.handleClose();
|
|
33513
|
-
}
|
|
33514
|
-
}
|
|
33515
33513
|
render() {
|
|
33516
33514
|
return html`
|
|
33517
|
-
<div class="backdrop"
|
|
33515
|
+
<div class="backdrop"></div>
|
|
33518
33516
|
<div class="container">
|
|
33519
33517
|
<button class="close-button" @click=${this.handleClose}>×</button>
|
|
33520
33518
|
|
|
@@ -33551,11 +33549,12 @@ SessionStartModal.styles = css`
|
|
|
33551
33549
|
left: 50%;
|
|
33552
33550
|
transform: translate(-50%, -50%);
|
|
33553
33551
|
z-index: 50;
|
|
33552
|
+
gap: 32px;
|
|
33554
33553
|
|
|
33555
33554
|
/* Layout from user specifications */
|
|
33556
33555
|
display: flex;
|
|
33557
33556
|
width: 640px;
|
|
33558
|
-
height: 380px;
|
|
33557
|
+
min-height: 380px;
|
|
33559
33558
|
padding: 48px 48px 32px 48px;
|
|
33560
33559
|
flex-direction: column;
|
|
33561
33560
|
justify-content: space-between;
|
|
@@ -33587,7 +33586,7 @@ SessionStartModal.styles = css`
|
|
|
33587
33586
|
align-items: center;
|
|
33588
33587
|
gap: 8px;
|
|
33589
33588
|
aspect-ratio: 1/1;
|
|
33590
|
-
border-radius: var(--border-radius-lg,
|
|
33589
|
+
border-radius: var(--border-radius-lg, 12px);
|
|
33591
33590
|
background: var(--tailwind-colors-violet-600, #7c3aed);
|
|
33592
33591
|
box-shadow:
|
|
33593
33592
|
0px 0px 8px 0px rgba(168, 85, 247, 0.12),
|
|
@@ -33609,15 +33608,15 @@ SessionStartModal.styles = css`
|
|
|
33609
33608
|
font-family: "Syne", sans-serif;
|
|
33610
33609
|
font-size: 32px;
|
|
33611
33610
|
font-weight: 700;
|
|
33612
|
-
margin: 32px 0 0 0;
|
|
33613
33611
|
color: #111827;
|
|
33612
|
+
margin: 0;
|
|
33614
33613
|
}
|
|
33615
33614
|
|
|
33616
33615
|
.subtitle {
|
|
33617
33616
|
font-size: 16px;
|
|
33618
33617
|
color: #6b7280;
|
|
33619
|
-
margin: 16px 0 0 0;
|
|
33620
33618
|
line-height: 1.5;
|
|
33619
|
+
margin: 0;
|
|
33621
33620
|
}
|
|
33622
33621
|
|
|
33623
33622
|
.button {
|
|
@@ -33695,11 +33694,13 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
33695
33694
|
__defProp(target, key, result);
|
|
33696
33695
|
return result;
|
|
33697
33696
|
};
|
|
33697
|
+
const WIDGET_PARAMS_KEY = "io.obi.widget-parameters";
|
|
33698
33698
|
class ObiWidget extends LitElement {
|
|
33699
33699
|
constructor() {
|
|
33700
33700
|
super();
|
|
33701
33701
|
this.apiKey = "";
|
|
33702
33702
|
this.isActive = true;
|
|
33703
|
+
this.linkOnlyAccess = false;
|
|
33703
33704
|
this.position = "bottom-right";
|
|
33704
33705
|
this.user = null;
|
|
33705
33706
|
this.state = SDKState.READY;
|
|
@@ -33721,6 +33722,7 @@ class ObiWidget extends LitElement {
|
|
|
33721
33722
|
this.boundSaveSessionData = null;
|
|
33722
33723
|
this.obiClient = null;
|
|
33723
33724
|
this.closeNavTimeoutRef = null;
|
|
33725
|
+
this.researchingTimeoutRef = null;
|
|
33724
33726
|
this.handleCourseSelectEvent = (event) => {
|
|
33725
33727
|
const customEvent = event;
|
|
33726
33728
|
this.selectedCourse = customEvent.detail;
|
|
@@ -33741,10 +33743,13 @@ class ObiWidget extends LitElement {
|
|
|
33741
33743
|
const sessionWithPlan = matchingSession;
|
|
33742
33744
|
this.selectedCourse = {
|
|
33743
33745
|
id: sessionToken,
|
|
33744
|
-
name: sessionWithPlan.onboarding_plan?.
|
|
33745
|
-
description: sessionWithPlan.onboarding_plan?.
|
|
33746
|
+
name: sessionWithPlan.onboarding_plan?.name || "",
|
|
33747
|
+
description: sessionWithPlan.onboarding_plan?.description || ""
|
|
33746
33748
|
};
|
|
33749
|
+
this.state = SDKState.LOADING;
|
|
33747
33750
|
this.showSessionStartModal = true;
|
|
33751
|
+
} else {
|
|
33752
|
+
console.log("No session found with token:", sessionToken);
|
|
33748
33753
|
}
|
|
33749
33754
|
}
|
|
33750
33755
|
} catch (error) {
|
|
@@ -33771,15 +33776,22 @@ class ObiWidget extends LitElement {
|
|
|
33771
33776
|
if (window.obiWidgetConfig.isActive !== void 0) {
|
|
33772
33777
|
this.isActive = window.obiWidgetConfig.isActive;
|
|
33773
33778
|
}
|
|
33779
|
+
if (window.obiWidgetConfig.linkOnlyAccess !== void 0) {
|
|
33780
|
+
this.linkOnlyAccess = window.obiWidgetConfig.linkOnlyAccess;
|
|
33781
|
+
}
|
|
33774
33782
|
this.style.setProperty("--obi-primary", window.obiWidgetConfig?.primaryColor || "#9500ff");
|
|
33775
33783
|
this.style.setProperty("--obi-secondary", window.obiWidgetConfig?.secondaryColor || "#c4b5fd");
|
|
33776
33784
|
}
|
|
33777
33785
|
}
|
|
33778
|
-
|
|
33786
|
+
removeSessionUrlParams() {
|
|
33779
33787
|
const url = new URL(window.location.href);
|
|
33780
33788
|
url.searchParams.delete(SESSION_URL_PARAM);
|
|
33781
|
-
url.searchParams.delete(API_KEY_URL_PARAM);
|
|
33782
33789
|
window.history.replaceState({}, "", url.toString());
|
|
33790
|
+
try {
|
|
33791
|
+
localStorage.removeItem(WIDGET_PARAMS_KEY);
|
|
33792
|
+
} catch (error) {
|
|
33793
|
+
console.warn("Failed to remove widget parameters from localStorage:", error);
|
|
33794
|
+
}
|
|
33783
33795
|
}
|
|
33784
33796
|
/**
|
|
33785
33797
|
* Create a new ObiSession instance with common configuration
|
|
@@ -33805,9 +33817,27 @@ class ObiWidget extends LitElement {
|
|
|
33805
33817
|
*/
|
|
33806
33818
|
setupSessionEventListeners(session, onError) {
|
|
33807
33819
|
session.on("stateChanged", (newState) => {
|
|
33808
|
-
|
|
33809
|
-
|
|
33820
|
+
if (newState === SDKState.RESEARCHING) {
|
|
33821
|
+
if (this.researchingTimeoutRef) {
|
|
33822
|
+
window.clearTimeout(this.researchingTimeoutRef);
|
|
33823
|
+
}
|
|
33824
|
+
this.state = newState;
|
|
33825
|
+
this.researchingTimeoutRef = window.setTimeout(() => {
|
|
33826
|
+
this.researchingTimeoutRef = null;
|
|
33827
|
+
const currentSessionState = session.getCurrentState();
|
|
33828
|
+
this.state = currentSessionState;
|
|
33829
|
+
if (currentSessionState !== SDKState.READY) {
|
|
33830
|
+
this.storedActiveState = currentSessionState;
|
|
33831
|
+
}
|
|
33832
|
+
}, 1500);
|
|
33810
33833
|
this.storedActiveState = newState;
|
|
33834
|
+
return;
|
|
33835
|
+
}
|
|
33836
|
+
if (this.researchingTimeoutRef === null) {
|
|
33837
|
+
this.state = newState;
|
|
33838
|
+
if (newState !== SDKState.READY) {
|
|
33839
|
+
this.storedActiveState = newState;
|
|
33840
|
+
}
|
|
33811
33841
|
}
|
|
33812
33842
|
});
|
|
33813
33843
|
session.on("volume", ({ speaker, spectrum, volume }) => {
|
|
@@ -33840,10 +33870,10 @@ class ObiWidget extends LitElement {
|
|
|
33840
33870
|
try {
|
|
33841
33871
|
const session = this.createSession(sessionToken);
|
|
33842
33872
|
if (!session) {
|
|
33843
|
-
this.handleSessionCreationFailure(() => this.
|
|
33873
|
+
this.handleSessionCreationFailure(() => this.removeSessionUrlParams());
|
|
33844
33874
|
return;
|
|
33845
33875
|
}
|
|
33846
|
-
this.setupSessionEventListeners(session, () => this.
|
|
33876
|
+
this.setupSessionEventListeners(session, () => this.removeSessionUrlParams());
|
|
33847
33877
|
session.on("screenCaptureRequested", async () => {
|
|
33848
33878
|
try {
|
|
33849
33879
|
const canvas = await html2canvas(document.documentElement, {
|
|
@@ -33863,12 +33893,12 @@ class ObiWidget extends LitElement {
|
|
|
33863
33893
|
this.sessionToken = sessionToken;
|
|
33864
33894
|
this.roomToken = connectionInfo.token;
|
|
33865
33895
|
this.roomUrl = connectionInfo.url;
|
|
33866
|
-
this.
|
|
33896
|
+
this.removeSessionUrlParams();
|
|
33867
33897
|
}
|
|
33868
33898
|
this.activeSession = session;
|
|
33869
33899
|
} catch (error) {
|
|
33870
33900
|
console.error("Failed to start session:", error);
|
|
33871
|
-
this.handleSessionCreationFailure(() => this.
|
|
33901
|
+
this.handleSessionCreationFailure(() => this.removeSessionUrlParams());
|
|
33872
33902
|
}
|
|
33873
33903
|
}
|
|
33874
33904
|
async handleSessionStart(sessionToken) {
|
|
@@ -33949,11 +33979,26 @@ class ObiWidget extends LitElement {
|
|
|
33949
33979
|
async sessionConnectionCheck() {
|
|
33950
33980
|
await this.checkExistingSession();
|
|
33951
33981
|
if (!this.activeSession) {
|
|
33952
|
-
|
|
33953
|
-
|
|
33954
|
-
|
|
33982
|
+
let storedParams = {};
|
|
33983
|
+
try {
|
|
33984
|
+
const storedParamsJson = localStorage.getItem(WIDGET_PARAMS_KEY);
|
|
33985
|
+
if (storedParamsJson) {
|
|
33986
|
+
storedParams = JSON.parse(storedParamsJson);
|
|
33987
|
+
}
|
|
33988
|
+
} catch (error) {
|
|
33989
|
+
console.warn("Failed to parse stored widget parameters:", error);
|
|
33990
|
+
}
|
|
33991
|
+
if (Object.keys(storedParams).length === 0) {
|
|
33992
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
33993
|
+
urlParams.forEach((value, key) => {
|
|
33994
|
+
storedParams[key] = value;
|
|
33995
|
+
});
|
|
33996
|
+
}
|
|
33997
|
+
const sessionId = storedParams[SESSION_URL_PARAM];
|
|
33955
33998
|
if (sessionId && this.apiKey) {
|
|
33956
33999
|
await this.handleUrlSessionEvent(sessionId);
|
|
34000
|
+
} else {
|
|
34001
|
+
console.log("No session ID found or API key is not set");
|
|
33957
34002
|
}
|
|
33958
34003
|
}
|
|
33959
34004
|
}
|
|
@@ -33970,11 +34015,15 @@ class ObiWidget extends LitElement {
|
|
|
33970
34015
|
if (this.closeNavTimeoutRef !== null) {
|
|
33971
34016
|
window.clearTimeout(this.closeNavTimeoutRef);
|
|
33972
34017
|
}
|
|
34018
|
+
if (this.researchingTimeoutRef !== null) {
|
|
34019
|
+
window.clearTimeout(this.researchingTimeoutRef);
|
|
34020
|
+
this.researchingTimeoutRef = null;
|
|
34021
|
+
}
|
|
33973
34022
|
if (this.boundSaveSessionData) {
|
|
33974
34023
|
window.removeEventListener("beforeunload", this.boundSaveSessionData);
|
|
33975
34024
|
window.removeEventListener("pagehide", this.boundSaveSessionData);
|
|
33976
34025
|
}
|
|
33977
|
-
this.
|
|
34026
|
+
this.removeSessionUrlParams();
|
|
33978
34027
|
super.disconnectedCallback();
|
|
33979
34028
|
}
|
|
33980
34029
|
handleMouseEnter() {
|
|
@@ -34002,6 +34051,10 @@ class ObiWidget extends LitElement {
|
|
|
34002
34051
|
this.sessionToken = null;
|
|
34003
34052
|
this.roomToken = null;
|
|
34004
34053
|
this.roomUrl = null;
|
|
34054
|
+
if (this.researchingTimeoutRef !== null) {
|
|
34055
|
+
window.clearTimeout(this.researchingTimeoutRef);
|
|
34056
|
+
this.researchingTimeoutRef = null;
|
|
34057
|
+
}
|
|
34005
34058
|
if (this.activeSession) {
|
|
34006
34059
|
this.activeSession.disconnect();
|
|
34007
34060
|
this.activeSession = null;
|
|
@@ -34026,13 +34079,26 @@ class ObiWidget extends LitElement {
|
|
|
34026
34079
|
render() {
|
|
34027
34080
|
if (!this.isActive)
|
|
34028
34081
|
return nothing;
|
|
34082
|
+
if (this.linkOnlyAccess && this.state === SDKState.READY)
|
|
34083
|
+
return nothing;
|
|
34029
34084
|
const stateRender = z$2(this.state).with(SDKState.LOADING, () => html`<obi-dot-loader></obi-dot-loader>`).with(SDKState.RESEARCHING, () => html`<obi-searching-loader></obi-searching-loader>`).with(
|
|
34030
34085
|
N$1.union(SDKState.USER_SPEAKING, SDKState.AGENT_SPEAKING),
|
|
34031
34086
|
() => html`<obi-audio-equalizer .volume=${this.volume}></obi-audio-equalizer>`
|
|
34032
|
-
).with(SDKState.PAUSED, () => obiIcon).otherwise(() => obiIcon);
|
|
34087
|
+
).with(SDKState.THINKING, () => html`<obi-dot-loader></obi-dot-loader>`).with(SDKState.PAUSED, () => obiIcon).otherwise(() => obiIcon);
|
|
34088
|
+
const isPulseState = this.state === SDKState.USER_SPEAKING || this.state === SDKState.AGENT_SPEAKING;
|
|
34089
|
+
const isResearching = this.state === SDKState.RESEARCHING;
|
|
34090
|
+
const isUserSpeaking = this.state === SDKState.USER_SPEAKING;
|
|
34091
|
+
const isRotated = this.state !== SDKState.READY || this.navVisible;
|
|
34092
|
+
const containerClasses = [
|
|
34093
|
+
"widget-container",
|
|
34094
|
+
isRotated ? "rotated" : "",
|
|
34095
|
+
isPulseState ? "pulse" : "",
|
|
34096
|
+
isResearching ? "researching" : "",
|
|
34097
|
+
isUserSpeaking ? "user-speaking" : ""
|
|
34098
|
+
].filter(Boolean).join(" ");
|
|
34033
34099
|
return html`
|
|
34034
34100
|
<div
|
|
34035
|
-
class="
|
|
34101
|
+
class="${containerClasses}"
|
|
34036
34102
|
@mouseenter=${this.handleMouseEnter}
|
|
34037
34103
|
@mouseleave=${this.handleMouseLeave}
|
|
34038
34104
|
>
|
|
@@ -34058,6 +34124,8 @@ class ObiWidget extends LitElement {
|
|
|
34058
34124
|
.onClose=${() => {
|
|
34059
34125
|
this.showSessionStartModal = false;
|
|
34060
34126
|
this.selectedCourse = null;
|
|
34127
|
+
this.state = SDKState.READY;
|
|
34128
|
+
this.removeSessionUrlParams();
|
|
34061
34129
|
}}
|
|
34062
34130
|
></obi-session-start-modal>` : nothing}
|
|
34063
34131
|
`;
|
|
@@ -34140,7 +34208,7 @@ ObiWidget.styles = css`
|
|
|
34140
34208
|
position: fixed;
|
|
34141
34209
|
width: 56px;
|
|
34142
34210
|
height: 56px;
|
|
34143
|
-
border-radius:
|
|
34211
|
+
border-radius: 12px;
|
|
34144
34212
|
border-color: transparent;
|
|
34145
34213
|
background-color: var(--obi-primary);
|
|
34146
34214
|
display: flex;
|
|
@@ -34156,17 +34224,8 @@ ObiWidget.styles = css`
|
|
|
34156
34224
|
linear-gradient(195.84deg, var(--obi-secondary) 00 11.05%, var(--obi-secondary) 117.01%);
|
|
34157
34225
|
}
|
|
34158
34226
|
|
|
34159
|
-
.widget-container:hover {
|
|
34160
|
-
border-radius: 12px;
|
|
34161
|
-
}
|
|
34162
|
-
|
|
34163
|
-
.widget-container.rounded {
|
|
34164
|
-
border-radius: 12px;
|
|
34165
|
-
}
|
|
34166
|
-
|
|
34167
34227
|
.widget-container.researching {
|
|
34168
34228
|
width: 273px;
|
|
34169
|
-
border-radius: 12px;
|
|
34170
34229
|
}
|
|
34171
34230
|
|
|
34172
34231
|
.widget-icon {
|
|
@@ -34175,7 +34234,7 @@ ObiWidget.styles = css`
|
|
|
34175
34234
|
transition: transform 0.5s ease-in-out;
|
|
34176
34235
|
}
|
|
34177
34236
|
|
|
34178
|
-
.widget-container.
|
|
34237
|
+
.widget-container.rotated .widget-icon {
|
|
34179
34238
|
transform: rotate(90deg);
|
|
34180
34239
|
}
|
|
34181
34240
|
|
|
@@ -34201,6 +34260,9 @@ __decorateClass([
|
|
|
34201
34260
|
__decorateClass([
|
|
34202
34261
|
r$2()
|
|
34203
34262
|
], ObiWidget.prototype, "isActive", 2);
|
|
34263
|
+
__decorateClass([
|
|
34264
|
+
r$2()
|
|
34265
|
+
], ObiWidget.prototype, "linkOnlyAccess", 2);
|
|
34204
34266
|
__decorateClass([
|
|
34205
34267
|
r$2()
|
|
34206
34268
|
], ObiWidget.prototype, "position", 2);
|
|
@@ -34240,6 +34302,36 @@ if (!customElements.get("obi-widget")) {
|
|
|
34240
34302
|
if (!customElements.get("obi-widget")) {
|
|
34241
34303
|
customElements.define("obi-widget", ObiWidget);
|
|
34242
34304
|
}
|
|
34305
|
+
const RETRY_CONFIG = {
|
|
34306
|
+
maxAttempts: 3,
|
|
34307
|
+
baseDelay: 200,
|
|
34308
|
+
// ms
|
|
34309
|
+
maxDelay: 2e3
|
|
34310
|
+
// ms
|
|
34311
|
+
};
|
|
34312
|
+
function delay(ms) {
|
|
34313
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
34314
|
+
}
|
|
34315
|
+
function getRetryDelay(attempt) {
|
|
34316
|
+
const exponentialDelay = RETRY_CONFIG.baseDelay * Math.pow(2, attempt);
|
|
34317
|
+
return Math.min(exponentialDelay, RETRY_CONFIG.maxDelay);
|
|
34318
|
+
}
|
|
34319
|
+
async function retryOperation(operation, operationName, maxAttempts = RETRY_CONFIG.maxAttempts) {
|
|
34320
|
+
let lastError = null;
|
|
34321
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
34322
|
+
try {
|
|
34323
|
+
return await operation();
|
|
34324
|
+
} catch (error) {
|
|
34325
|
+
lastError = error;
|
|
34326
|
+
console.warn(`${operationName} failed (attempt ${attempt + 1}/${maxAttempts}):`, error);
|
|
34327
|
+
if (attempt < maxAttempts - 1) {
|
|
34328
|
+
const delayMs = getRetryDelay(attempt);
|
|
34329
|
+
await delay(delayMs);
|
|
34330
|
+
}
|
|
34331
|
+
}
|
|
34332
|
+
}
|
|
34333
|
+
throw new Error(`${operationName} failed after ${maxAttempts} attempts: ${lastError?.message}`);
|
|
34334
|
+
}
|
|
34243
34335
|
function mountSDK() {
|
|
34244
34336
|
const w2 = window;
|
|
34245
34337
|
if (typeof w2.ObiSDK === "function" || typeof w2.ObiSDK === "object") {
|
|
@@ -34255,12 +34347,18 @@ function mountSDK() {
|
|
|
34255
34347
|
};
|
|
34256
34348
|
w2.ObiSDK.q = [];
|
|
34257
34349
|
}
|
|
34258
|
-
function mountWidget() {
|
|
34259
|
-
|
|
34350
|
+
async function mountWidget() {
|
|
34351
|
+
return retryOperation(async () => {
|
|
34352
|
+
if (document.querySelector("obi-widget")) {
|
|
34353
|
+
return;
|
|
34354
|
+
}
|
|
34355
|
+
if (!document.body) {
|
|
34356
|
+
throw new Error("document.body not available");
|
|
34357
|
+
}
|
|
34260
34358
|
const widget = document.createElement("obi-widget");
|
|
34261
34359
|
document.body.appendChild(widget);
|
|
34262
34360
|
console.log("Obi Widget mounted");
|
|
34263
|
-
}
|
|
34361
|
+
}, "Widget mounting");
|
|
34264
34362
|
}
|
|
34265
34363
|
function processQueue() {
|
|
34266
34364
|
const w2 = window;
|
|
@@ -34277,17 +34375,62 @@ function processQueue() {
|
|
|
34277
34375
|
w2.ObiSDK.q = [];
|
|
34278
34376
|
}
|
|
34279
34377
|
}
|
|
34280
|
-
function loadFonts() {
|
|
34281
|
-
|
|
34282
|
-
|
|
34283
|
-
|
|
34284
|
-
|
|
34378
|
+
async function loadFonts() {
|
|
34379
|
+
return retryOperation(async () => {
|
|
34380
|
+
if (!document.head) {
|
|
34381
|
+
throw new Error("document.head not available");
|
|
34382
|
+
}
|
|
34383
|
+
const existingLink = document.head.querySelector('link[href*="fonts.googleapis.com"]');
|
|
34384
|
+
if (existingLink) {
|
|
34385
|
+
return;
|
|
34386
|
+
}
|
|
34387
|
+
const link = document.createElement("link");
|
|
34388
|
+
document.head.querySelectorAll("link[data-obi-font]").forEach((node) => node.remove());
|
|
34389
|
+
link.setAttribute("data-obi-font", "true");
|
|
34390
|
+
link.href = "https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&family=Syne:wght@400..800&display=swap";
|
|
34391
|
+
link.rel = "stylesheet";
|
|
34392
|
+
return new Promise((resolve, reject) => {
|
|
34393
|
+
const timeout = setTimeout(() => {
|
|
34394
|
+
reject(new Error("Font loading timeout"));
|
|
34395
|
+
}, 5e3);
|
|
34396
|
+
link.onload = () => {
|
|
34397
|
+
clearTimeout(timeout);
|
|
34398
|
+
resolve();
|
|
34399
|
+
};
|
|
34400
|
+
link.onerror = () => {
|
|
34401
|
+
clearTimeout(timeout);
|
|
34402
|
+
reject(new Error("Font loading failed"));
|
|
34403
|
+
};
|
|
34404
|
+
document.head.appendChild(link);
|
|
34405
|
+
});
|
|
34406
|
+
}, "Font loading");
|
|
34407
|
+
}
|
|
34408
|
+
async function safeInitialize() {
|
|
34409
|
+
try {
|
|
34410
|
+
mountSDK();
|
|
34411
|
+
await loadFonts();
|
|
34412
|
+
await mountWidget();
|
|
34413
|
+
processQueue();
|
|
34414
|
+
console.log("Obi Widget initialized successfully");
|
|
34415
|
+
} catch (error) {
|
|
34416
|
+
console.error("Obi Widget initialization failed:", error);
|
|
34417
|
+
try {
|
|
34418
|
+
mountSDK();
|
|
34419
|
+
processQueue();
|
|
34420
|
+
console.log("Obi Widget fallback initialization completed");
|
|
34421
|
+
} catch (fallbackError) {
|
|
34422
|
+
console.error("Obi Widget fallback initialization failed:", fallbackError);
|
|
34423
|
+
}
|
|
34424
|
+
}
|
|
34285
34425
|
}
|
|
34286
34426
|
function initializeObiWidget() {
|
|
34287
|
-
|
|
34288
|
-
|
|
34289
|
-
|
|
34290
|
-
|
|
34427
|
+
if (document.readyState === "loading") {
|
|
34428
|
+
document.addEventListener("DOMContentLoaded", () => {
|
|
34429
|
+
safeInitialize();
|
|
34430
|
+
});
|
|
34431
|
+
} else {
|
|
34432
|
+
safeInitialize();
|
|
34433
|
+
}
|
|
34291
34434
|
}
|
|
34292
34435
|
initializeObiWidget();
|
|
34293
34436
|
export {
|