obi-sdk 0.4.0 → 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.
@@ -1,4 +1,4 @@
1
- import { A, S } from "./chunks/types-82772f00.js";
1
+ import { A, S } from "./chunks/types-e0297e7b.js";
2
2
  var util;
3
3
  (function(util2) {
4
4
  util2.assertEqual = (val) => val;
@@ -1,8 +1,38 @@
1
- import { O as ObiWidget } from "./chunks/obi-widget-9ef6796a.js";
2
- import "./chunks/types-82772f00.js";
1
+ import { O as ObiWidget } from "./chunks/obi-widget-58dc98b0.js";
2
+ import "./chunks/types-e0297e7b.js";
3
3
  if (!customElements.get("obi-widget")) {
4
4
  customElements.define("obi-widget", ObiWidget);
5
5
  }
6
+ const RETRY_CONFIG = {
7
+ maxAttempts: 3,
8
+ baseDelay: 200,
9
+ // ms
10
+ maxDelay: 2e3
11
+ // ms
12
+ };
13
+ function delay(ms) {
14
+ return new Promise((resolve) => setTimeout(resolve, ms));
15
+ }
16
+ function getRetryDelay(attempt) {
17
+ const exponentialDelay = RETRY_CONFIG.baseDelay * Math.pow(2, attempt);
18
+ return Math.min(exponentialDelay, RETRY_CONFIG.maxDelay);
19
+ }
20
+ async function retryOperation(operation, operationName, maxAttempts = RETRY_CONFIG.maxAttempts) {
21
+ let lastError = null;
22
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
23
+ try {
24
+ return await operation();
25
+ } catch (error) {
26
+ lastError = error;
27
+ console.warn(`${operationName} failed (attempt ${attempt + 1}/${maxAttempts}):`, error);
28
+ if (attempt < maxAttempts - 1) {
29
+ const delayMs = getRetryDelay(attempt);
30
+ await delay(delayMs);
31
+ }
32
+ }
33
+ }
34
+ throw new Error(`${operationName} failed after ${maxAttempts} attempts: ${lastError?.message}`);
35
+ }
6
36
  function mountSDK() {
7
37
  const w = window;
8
38
  if (typeof w.ObiSDK === "function" || typeof w.ObiSDK === "object") {
@@ -18,12 +48,18 @@ function mountSDK() {
18
48
  };
19
49
  w.ObiSDK.q = [];
20
50
  }
21
- function mountWidget() {
22
- if (!document.querySelector("obi-widget")) {
51
+ async function mountWidget() {
52
+ return retryOperation(async () => {
53
+ if (document.querySelector("obi-widget")) {
54
+ return;
55
+ }
56
+ if (!document.body) {
57
+ throw new Error("document.body not available");
58
+ }
23
59
  const widget = document.createElement("obi-widget");
24
60
  document.body.appendChild(widget);
25
61
  console.log("Obi Widget mounted");
26
- }
62
+ }, "Widget mounting");
27
63
  }
28
64
  function processQueue() {
29
65
  const w = window;
@@ -40,17 +76,62 @@ function processQueue() {
40
76
  w.ObiSDK.q = [];
41
77
  }
42
78
  }
43
- function loadFonts() {
44
- const link = document.createElement("link");
45
- 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";
46
- link.rel = "stylesheet";
47
- document.head.appendChild(link);
79
+ async function loadFonts() {
80
+ return retryOperation(async () => {
81
+ if (!document.head) {
82
+ throw new Error("document.head not available");
83
+ }
84
+ const existingLink = document.head.querySelector('link[href*="fonts.googleapis.com"]');
85
+ if (existingLink) {
86
+ return;
87
+ }
88
+ const link = document.createElement("link");
89
+ document.head.querySelectorAll("link[data-obi-font]").forEach((node) => node.remove());
90
+ link.setAttribute("data-obi-font", "true");
91
+ 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";
92
+ link.rel = "stylesheet";
93
+ return new Promise((resolve, reject) => {
94
+ const timeout = setTimeout(() => {
95
+ reject(new Error("Font loading timeout"));
96
+ }, 5e3);
97
+ link.onload = () => {
98
+ clearTimeout(timeout);
99
+ resolve();
100
+ };
101
+ link.onerror = () => {
102
+ clearTimeout(timeout);
103
+ reject(new Error("Font loading failed"));
104
+ };
105
+ document.head.appendChild(link);
106
+ });
107
+ }, "Font loading");
108
+ }
109
+ async function safeInitialize() {
110
+ try {
111
+ mountSDK();
112
+ await loadFonts();
113
+ await mountWidget();
114
+ processQueue();
115
+ console.log("Obi Widget initialized successfully");
116
+ } catch (error) {
117
+ console.error("Obi Widget initialization failed:", error);
118
+ try {
119
+ mountSDK();
120
+ processQueue();
121
+ console.log("Obi Widget fallback initialization completed");
122
+ } catch (fallbackError) {
123
+ console.error("Obi Widget fallback initialization failed:", fallbackError);
124
+ }
125
+ }
48
126
  }
49
127
  function initializeObiWidget() {
50
- loadFonts();
51
- mountSDK();
52
- mountWidget();
53
- processQueue();
128
+ if (document.readyState === "loading") {
129
+ document.addEventListener("DOMContentLoaded", () => {
130
+ safeInitialize();
131
+ });
132
+ } else {
133
+ safeInitialize();
134
+ }
54
135
  }
55
136
  initializeObiWidget();
56
137
  export {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/core/init.ts"],"sourcesContent":["import { ObiWidget } from \"../ui/components/obi-widget\"\n\nif (!customElements.get(\"obi-widget\")) {\n customElements.define(\"obi-widget\", ObiWidget)\n}\n\nfunction mountSDK(): void {\n const w = window as any\n if (typeof w.ObiSDK === \"function\" || typeof w.ObiSDK === \"object\") {\n return\n }\n\n // Initialize the SDK\n w.ObiSDK = function (command: string, config?: any) {\n if (command === \"update\" && config) {\n w.obiWidgetConfig = {\n ...w.obiWidgetConfig,\n ...config,\n }\n }\n }\n w.ObiSDK.q = []\n}\n\n// Mount the widget if not already present\nfunction mountWidget() {\n if (!document.querySelector(\"obi-widget\")) {\n const widget = document.createElement(\"obi-widget\")\n document.body.appendChild(widget)\n console.log(\"Obi Widget mounted\")\n }\n}\n\n// Optionally process a queue if you want to support it\nfunction processQueue() {\n const w = window as any\n if (w.ObiSDK && Array.isArray(w.ObiSDK.q)) {\n // Process each command in the queue\n w.ObiSDK.q.forEach((args: any[]) => {\n const [command, config] = args\n if (command === \"update\" && config) {\n w.obiWidgetConfig = {\n ...w.obiWidgetConfig,\n ...config,\n }\n }\n })\n w.ObiSDK.q = []\n }\n}\n\nfunction loadFonts() {\n const link = document.createElement(\"link\")\n link.href =\n \"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\"\n link.rel = \"stylesheet\"\n document.head.appendChild(link)\n}\n\n// Main init\nexport function initializeObiWidget() {\n loadFonts()\n mountSDK()\n mountWidget()\n processQueue()\n}\n\n// Auto-initialize\ninitializeObiWidget()\n"],"names":[],"mappings":"AAEA,SAAA,KAAA,iBAAA;AAAA,OAAA;AAAA,IAAI,CAAC,eAAe,IAAI,YAAY,GAAG;AACtB,iBAAA,OAAO,cAAc,SAAS;AAC/C;AAEA,SAAS,WAAiB;AACxB,QAAM,IAAI;AACV,MAAI,OAAO,EAAE,WAAW,cAAc,OAAO,EAAE,WAAW,UAAU;AAClE;AAAA,EACF;AAGE,IAAA,SAAS,SAAU,SAAiB,QAAc;AAC9C,QAAA,YAAY,YAAY,QAAQ;AAClC,QAAE,kBAAkB;AAAA,QAClB,GAAG,EAAE;AAAA,QACL,GAAG;AAAA,MAAA;AAAA,IAEP;AAAA,EAAA;AAEA,IAAA,OAAO,IAAI;AACf;AAGA,SAAS,cAAc;AACrB,MAAI,CAAC,SAAS,cAAc,YAAY,GAAG;AACnC,UAAA,SAAS,SAAS,cAAc,YAAY;AACzC,aAAA,KAAK,YAAY,MAAM;AAChC,YAAQ,IAAI,oBAAoB;AAAA,EAClC;AACF;AAGA,SAAS,eAAe;AACtB,QAAM,IAAI;AACV,MAAI,EAAE,UAAU,MAAM,QAAQ,EAAE,OAAO,CAAC,GAAG;AAEzC,MAAE,OAAO,EAAE,QAAQ,CAAC,SAAgB;AAC5B,YAAA,CAAC,SAAS,MAAM,IAAI;AACtB,UAAA,YAAY,YAAY,QAAQ;AAClC,UAAE,kBAAkB;AAAA,UAClB,GAAG,EAAE;AAAA,UACL,GAAG;AAAA,QAAA;AAAA,MAEP;AAAA,IAAA,CACD;AACC,MAAA,OAAO,IAAI;EACf;AACF;AAEA,SAAS,YAAY;AACb,QAAA,OAAO,SAAS,cAAc,MAAM;AAC1C,OAAK,OACH;AACF,OAAK,MAAM;AACF,WAAA,KAAK,YAAY,IAAI;AAChC;AAGO,SAAS,sBAAsB;AAC1B;AACD;AACG;AACC;AACf;AAGA,oBAAoB;"}
1
+ {"version":3,"file":"index.js","sources":["../../src/core/init.ts"],"sourcesContent":["import { ObiWidget } from \"../ui/components/obi-widget\"\n\nif (!customElements.get(\"obi-widget\")) {\n customElements.define(\"obi-widget\", ObiWidget)\n}\n\n// Retry configuration\nconst RETRY_CONFIG = {\n maxAttempts: 3,\n baseDelay: 200, // ms\n maxDelay: 2000, // ms\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\nfunction getRetryDelay(attempt: number): number {\n const exponentialDelay = RETRY_CONFIG.baseDelay * Math.pow(2, attempt)\n return Math.min(exponentialDelay, RETRY_CONFIG.maxDelay)\n}\n\nasync function retryOperation<T>(\n operation: () => Promise<T> | T,\n operationName: string,\n maxAttempts: number = RETRY_CONFIG.maxAttempts\n): Promise<T> {\n let lastError: Error | null = null\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n return await operation()\n } catch (error) {\n lastError = error as Error\n console.warn(`${operationName} failed (attempt ${attempt + 1}/${maxAttempts}):`, error)\n\n if (attempt < maxAttempts - 1) {\n const delayMs = getRetryDelay(attempt)\n await delay(delayMs)\n }\n }\n }\n\n throw new Error(`${operationName} failed after ${maxAttempts} attempts: ${lastError?.message}`)\n}\n\nfunction mountSDK(): void {\n const w = window as any\n if (typeof w.ObiSDK === \"function\" || typeof w.ObiSDK === \"object\") {\n return\n }\n\n // Initialize the SDK\n w.ObiSDK = function (command: string, config?: any) {\n if (command === \"update\" && config) {\n w.obiWidgetConfig = {\n ...w.obiWidgetConfig,\n ...config,\n }\n }\n }\n w.ObiSDK.q = []\n}\n\n// Mount the widget if not already present\nasync function mountWidget(): Promise<void> {\n return retryOperation(async () => {\n if (document.querySelector(\"obi-widget\")) {\n return // Already mounted\n }\n\n if (!document.body) {\n throw new Error(\"document.body not available\")\n }\n\n const widget = document.createElement(\"obi-widget\")\n document.body.appendChild(widget)\n console.log(\"Obi Widget mounted\")\n }, \"Widget mounting\")\n}\n\n// Optionally process a queue if you want to support it\nfunction processQueue() {\n const w = window as any\n if (w.ObiSDK && Array.isArray(w.ObiSDK.q)) {\n // Process each command in the queue\n w.ObiSDK.q.forEach((args: any[]) => {\n const [command, config] = args\n if (command === \"update\" && config) {\n w.obiWidgetConfig = {\n ...w.obiWidgetConfig,\n ...config,\n }\n }\n })\n w.ObiSDK.q = []\n }\n}\n\nasync function loadFonts(): Promise<void> {\n return retryOperation(async () => {\n if (!document.head) {\n throw new Error(\"document.head not available\")\n }\n\n // Check if fonts are already loaded\n const existingLink = document.head.querySelector('link[href*=\"fonts.googleapis.com\"]')\n if (existingLink) {\n return // Already loaded\n }\n\n const link = document.createElement(\"link\")\n // Remove any previous failed link for a clean retry\n document.head.querySelectorAll(\"link[data-obi-font]\").forEach((node) => node.remove())\n link.setAttribute(\"data-obi-font\", \"true\")\n\n link.href =\n \"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\"\n link.rel = \"stylesheet\"\n\n // Wait for font load or timeout\n return new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(\"Font loading timeout\"))\n }, 5000)\n\n link.onload = () => {\n clearTimeout(timeout)\n resolve()\n }\n\n link.onerror = () => {\n clearTimeout(timeout)\n reject(new Error(\"Font loading failed\"))\n }\n\n document.head.appendChild(link)\n })\n }, \"Font loading\")\n}\n\nasync function safeInitialize(): Promise<void> {\n try {\n mountSDK()\n await loadFonts()\n await mountWidget()\n processQueue()\n console.log(\"Obi Widget initialized successfully\")\n } catch (error) {\n console.error(\"Obi Widget initialization failed:\", error)\n // Still try to mount basic functionality\n try {\n mountSDK()\n processQueue()\n console.log(\"Obi Widget fallback initialization completed\")\n } catch (fallbackError) {\n console.error(\"Obi Widget fallback initialization failed:\", fallbackError)\n }\n }\n}\n\n// Main init\nexport function initializeObiWidget() {\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", () => {\n safeInitialize()\n })\n } else {\n safeInitialize()\n }\n}\n\n// Auto-initialize\ninitializeObiWidget()\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- import { S as SDKState } from "./chunks/types-82772f00.js";
2
- import { i, n, a as i$1, x } from "./chunks/obi-widget-9ef6796a.js";
3
- import { A, C, c, d, D, N, b, O, S } from "./chunks/obi-widget-9ef6796a.js";
1
+ import { S as SDKState } from "./chunks/types-e0297e7b.js";
2
+ import { i, n, a as i$1, x } from "./chunks/obi-widget-58dc98b0.js";
3
+ import { A, C, c, d, D, N, b, O, S } from "./chunks/obi-widget-58dc98b0.js";
4
4
  var __defProp = Object.defineProperty;
5
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
6
  var __decorateClass = (decorators, target, key, kind) => {
@@ -85,14 +85,14 @@ if (!customElements.get("obi-status-widget")) {
85
85
  const statusWidget = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, ObiStatusWidget }, Symbol.toStringTag, { value: "Module" }));
86
86
  function defineCustomElements() {
87
87
  Promise.resolve().then(() => statusWidget);
88
- import("./chunks/obi-widget-9ef6796a.js").then((n2) => n2.o);
89
- import("./chunks/obi-widget-9ef6796a.js").then((n2) => n2.j);
90
- import("./chunks/obi-widget-9ef6796a.js").then((n2) => n2.k);
91
- import("./chunks/obi-widget-9ef6796a.js").then((n2) => n2.e);
92
- import("./chunks/obi-widget-9ef6796a.js").then((n2) => n2.f);
93
- import("./chunks/obi-widget-9ef6796a.js").then((n2) => n2.s);
94
- import("./chunks/obi-widget-9ef6796a.js").then((n2) => n2.g);
95
- import("./chunks/obi-widget-9ef6796a.js").then((n2) => n2.h);
88
+ import("./chunks/obi-widget-58dc98b0.js").then((n2) => n2.o);
89
+ import("./chunks/obi-widget-58dc98b0.js").then((n2) => n2.j);
90
+ import("./chunks/obi-widget-58dc98b0.js").then((n2) => n2.k);
91
+ import("./chunks/obi-widget-58dc98b0.js").then((n2) => n2.e);
92
+ import("./chunks/obi-widget-58dc98b0.js").then((n2) => n2.f);
93
+ import("./chunks/obi-widget-58dc98b0.js").then((n2) => n2.s);
94
+ import("./chunks/obi-widget-58dc98b0.js").then((n2) => n2.g);
95
+ import("./chunks/obi-widget-58dc98b0.js").then((n2) => n2.h);
96
96
  }
97
97
  export {
98
98
  A as AudioEqualizer,
@@ -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 delay = this.getNextRetryDelay({
15469
+ let delay2 = this.getNextRetryDelay({
15470
15470
  elapsedMs: duration2,
15471
15471
  retryCount: this.reconnectAttempts
15472
15472
  });
15473
- if (delay === null) {
15473
+ if (delay2 === null) {
15474
15474
  disconnect(duration2);
15475
15475
  return;
15476
15476
  }
15477
15477
  if (connection === leaveReconnect) {
15478
- delay = 0;
15478
+ delay2 = 0;
15479
15479
  }
15480
- this.log.debug("reconnecting in ".concat(delay, "ms"), this.logContext);
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), delay);
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) => {
@@ -23298,7 +23298,6 @@ class ObiSession {
23298
23298
  }
23299
23299
  }
23300
23300
  const SESSION_URL_PARAM = "49206C6F7665204F6269_session";
23301
- const API_KEY_URL_PARAM = "49206C6F7665204F6269_client";
23302
23301
  var extendStatics = function(d2, b2) {
23303
23302
  extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d3, b3) {
23304
23303
  d3.__proto__ = b3;
@@ -33393,7 +33392,7 @@ class DotLoader extends LitElement {
33393
33392
  animateSequence() {
33394
33393
  this.activeDots = Array(this.numDots).fill(false);
33395
33394
  for (let i2 = 0; i2 < this.numDots; i2++) {
33396
- const delay = i2 * (this.animationDuration * this.overlapFactor);
33395
+ const delay2 = i2 * (this.animationDuration * this.overlapFactor);
33397
33396
  const bounceStartId = window.setTimeout(() => {
33398
33397
  this.activeDots = [...this.activeDots];
33399
33398
  this.activeDots[i2] = true;
@@ -33402,7 +33401,7 @@ class DotLoader extends LitElement {
33402
33401
  this.activeDots[i2] = false;
33403
33402
  }, this.animationDuration);
33404
33403
  this.timeoutIds.push(bounceEndId);
33405
- }, delay);
33404
+ }, delay2);
33406
33405
  this.timeoutIds.push(bounceStartId);
33407
33406
  }
33408
33407
  const nextSequenceId = window.setTimeout(
@@ -33511,14 +33510,9 @@ class SessionStartModal extends LitElement {
33511
33510
  this.onClose();
33512
33511
  }
33513
33512
  }
33514
- handleBackdropClick(e2) {
33515
- if (e2.target === e2.currentTarget) {
33516
- this.handleClose();
33517
- }
33518
- }
33519
33513
  render() {
33520
33514
  return html`
33521
- <div class="backdrop" @click=${this.handleBackdropClick}></div>
33515
+ <div class="backdrop"></div>
33522
33516
  <div class="container">
33523
33517
  <button class="close-button" @click=${this.handleClose}>×</button>
33524
33518
 
@@ -33555,11 +33549,12 @@ SessionStartModal.styles = css`
33555
33549
  left: 50%;
33556
33550
  transform: translate(-50%, -50%);
33557
33551
  z-index: 50;
33552
+ gap: 32px;
33558
33553
 
33559
33554
  /* Layout from user specifications */
33560
33555
  display: flex;
33561
33556
  width: 640px;
33562
- height: 380px;
33557
+ min-height: 380px;
33563
33558
  padding: 48px 48px 32px 48px;
33564
33559
  flex-direction: column;
33565
33560
  justify-content: space-between;
@@ -33613,15 +33608,15 @@ SessionStartModal.styles = css`
33613
33608
  font-family: "Syne", sans-serif;
33614
33609
  font-size: 32px;
33615
33610
  font-weight: 700;
33616
- margin: 32px 0 0 0;
33617
33611
  color: #111827;
33612
+ margin: 0;
33618
33613
  }
33619
33614
 
33620
33615
  .subtitle {
33621
33616
  font-size: 16px;
33622
33617
  color: #6b7280;
33623
- margin: 16px 0 0 0;
33624
33618
  line-height: 1.5;
33619
+ margin: 0;
33625
33620
  }
33626
33621
 
33627
33622
  .button {
@@ -33751,6 +33746,7 @@ class ObiWidget extends LitElement {
33751
33746
  name: sessionWithPlan.onboarding_plan?.name || "",
33752
33747
  description: sessionWithPlan.onboarding_plan?.description || ""
33753
33748
  };
33749
+ this.state = SDKState.LOADING;
33754
33750
  this.showSessionStartModal = true;
33755
33751
  } else {
33756
33752
  console.log("No session found with token:", sessionToken);
@@ -33790,7 +33786,6 @@ class ObiWidget extends LitElement {
33790
33786
  removeSessionUrlParams() {
33791
33787
  const url = new URL(window.location.href);
33792
33788
  url.searchParams.delete(SESSION_URL_PARAM);
33793
- url.searchParams.delete(API_KEY_URL_PARAM);
33794
33789
  window.history.replaceState({}, "", url.toString());
33795
33790
  try {
33796
33791
  localStorage.removeItem(WIDGET_PARAMS_KEY);
@@ -34000,14 +33995,10 @@ class ObiWidget extends LitElement {
34000
33995
  });
34001
33996
  }
34002
33997
  const sessionId = storedParams[SESSION_URL_PARAM];
34003
- const urlApiKey = storedParams[API_KEY_URL_PARAM];
34004
- if (urlApiKey) {
34005
- this.apiKey = urlApiKey;
34006
- } else if (!this.apiKey && window.obiWidgetConfig?.apiKey) {
34007
- this.apiKey = window.obiWidgetConfig.apiKey;
34008
- }
34009
33998
  if (sessionId && this.apiKey) {
34010
33999
  await this.handleUrlSessionEvent(sessionId);
34000
+ } else {
34001
+ console.log("No session ID found or API key is not set");
34011
34002
  }
34012
34003
  }
34013
34004
  }
@@ -34133,6 +34124,8 @@ class ObiWidget extends LitElement {
34133
34124
  .onClose=${() => {
34134
34125
  this.showSessionStartModal = false;
34135
34126
  this.selectedCourse = null;
34127
+ this.state = SDKState.READY;
34128
+ this.removeSessionUrlParams();
34136
34129
  }}
34137
34130
  ></obi-session-start-modal>` : nothing}
34138
34131
  `;
@@ -34309,6 +34302,36 @@ if (!customElements.get("obi-widget")) {
34309
34302
  if (!customElements.get("obi-widget")) {
34310
34303
  customElements.define("obi-widget", ObiWidget);
34311
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
+ }
34312
34335
  function mountSDK() {
34313
34336
  const w2 = window;
34314
34337
  if (typeof w2.ObiSDK === "function" || typeof w2.ObiSDK === "object") {
@@ -34324,12 +34347,18 @@ function mountSDK() {
34324
34347
  };
34325
34348
  w2.ObiSDK.q = [];
34326
34349
  }
34327
- function mountWidget() {
34328
- if (!document.querySelector("obi-widget")) {
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
+ }
34329
34358
  const widget = document.createElement("obi-widget");
34330
34359
  document.body.appendChild(widget);
34331
34360
  console.log("Obi Widget mounted");
34332
- }
34361
+ }, "Widget mounting");
34333
34362
  }
34334
34363
  function processQueue() {
34335
34364
  const w2 = window;
@@ -34346,17 +34375,62 @@ function processQueue() {
34346
34375
  w2.ObiSDK.q = [];
34347
34376
  }
34348
34377
  }
34349
- function loadFonts() {
34350
- const link = document.createElement("link");
34351
- 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";
34352
- link.rel = "stylesheet";
34353
- document.head.appendChild(link);
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
+ }
34354
34425
  }
34355
34426
  function initializeObiWidget() {
34356
- loadFonts();
34357
- mountSDK();
34358
- mountWidget();
34359
- processQueue();
34427
+ if (document.readyState === "loading") {
34428
+ document.addEventListener("DOMContentLoaded", () => {
34429
+ safeInitialize();
34430
+ });
34431
+ } else {
34432
+ safeInitialize();
34433
+ }
34360
34434
  }
34361
34435
  initializeObiWidget();
34362
34436
  export {