obi-sdk 0.4.0 → 0.4.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.
@@ -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-2ba751b3.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
+ await loadFont("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");
81
+ await loadFont("https://fonts.cdnfonts.com/css/satoshi");
82
+ }
83
+ async function loadFont(fontUrl) {
84
+ return retryOperation(async () => {
85
+ if (!document.head) {
86
+ throw new Error("document.head not available");
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 = fontUrl;
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 await loadFont(\"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 await loadFont(\"https://fonts.cdnfonts.com/css/satoshi\")\n}\n\nasync function loadFont(fontUrl: string): 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 = fontUrl\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-2ba751b3.js";
3
+ import { A, C, c, d, D, N, b, O, S } from "./chunks/obi-widget-2ba751b3.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-2ba751b3.js").then((n2) => n2.o);
89
+ import("./chunks/obi-widget-2ba751b3.js").then((n2) => n2.j);
90
+ import("./chunks/obi-widget-2ba751b3.js").then((n2) => n2.k);
91
+ import("./chunks/obi-widget-2ba751b3.js").then((n2) => n2.e);
92
+ import("./chunks/obi-widget-2ba751b3.js").then((n2) => n2.f);
93
+ import("./chunks/obi-widget-2ba751b3.js").then((n2) => n2.s);
94
+ import("./chunks/obi-widget-2ba751b3.js").then((n2) => n2.g);
95
+ import("./chunks/obi-widget-2ba751b3.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
 
@@ -33528,7 +33522,7 @@ class SessionStartModal extends LitElement {
33528
33522
  <p class="subtitle">${this.session.description}</p>
33529
33523
  </div>
33530
33524
 
33531
- <button class="button button-primary" @click=${this.handleStart}>Continue →</button>
33525
+ <button class="button button-primary" @click=${this.handleStart}>Continue</button>
33532
33526
  </div>
33533
33527
  `;
33534
33528
  }
@@ -33537,6 +33531,7 @@ SessionStartModal.styles = css`
33537
33531
  :host {
33538
33532
  display: block;
33539
33533
  font-family: "Inter", sans-serif;
33534
+ box-sizing: border-box;
33540
33535
  }
33541
33536
 
33542
33537
  .backdrop {
@@ -33550,6 +33545,7 @@ SessionStartModal.styles = css`
33550
33545
  }
33551
33546
 
33552
33547
  .container {
33548
+ box-sizing: border-box;
33553
33549
  position: fixed;
33554
33550
  top: 50%;
33555
33551
  left: 50%;
@@ -33559,8 +33555,8 @@ SessionStartModal.styles = css`
33559
33555
  /* Layout from user specifications */
33560
33556
  display: flex;
33561
33557
  width: 640px;
33562
- height: 380px;
33563
- padding: 48px 48px 32px 48px;
33558
+ min-height: 380px;
33559
+ padding: 32px;
33564
33560
  flex-direction: column;
33565
33561
  justify-content: space-between;
33566
33562
  align-items: center;
@@ -33579,20 +33575,17 @@ SessionStartModal.styles = css`
33579
33575
  flex-direction: column;
33580
33576
  align-items: center;
33581
33577
  text-align: center;
33582
- gap: 16px;
33583
33578
  }
33584
33579
 
33585
33580
  .logo {
33586
33581
  display: flex;
33587
33582
  width: 96px;
33588
33583
  height: 96px;
33589
- padding: 8px;
33590
33584
  justify-content: center;
33591
33585
  align-items: center;
33592
- gap: 8px;
33593
33586
  aspect-ratio: 1/1;
33594
- border-radius: var(--border-radius-lg, 12px);
33595
- background: var(--tailwind-colors-violet-600, #7c3aed);
33587
+ border-radius: 8px;
33588
+ background: var(--obi-primary, #a10fff);
33596
33589
  box-shadow:
33597
33590
  0px 0px 8px 0px rgba(168, 85, 247, 0.12),
33598
33591
  0px 0px 8px 0px rgba(192, 132, 252, 0.24),
@@ -33610,32 +33603,36 @@ SessionStartModal.styles = css`
33610
33603
  }
33611
33604
 
33612
33605
  h1 {
33613
- font-family: "Syne", sans-serif;
33606
+ font-family: "Satoshi", sans-serif;
33614
33607
  font-size: 32px;
33615
33608
  font-weight: 700;
33616
- margin: 32px 0 0 0;
33617
33609
  color: #111827;
33610
+ margin: 0;
33611
+ margin-top: 32px;
33612
+ margin-bottom: 16px;
33618
33613
  }
33619
33614
 
33620
33615
  .subtitle {
33616
+ font-family: "Satoshi", sans-serif;
33617
+ font-weight: 300;
33621
33618
  font-size: 16px;
33622
- color: #6b7280;
33623
- margin: 16px 0 0 0;
33624
- line-height: 1.5;
33619
+ color: #18181b;
33620
+ line-height: 1.4;
33621
+ margin: 0;
33625
33622
  }
33626
33623
 
33627
33624
  .button {
33625
+ font-family: "Satoshi", sans-serif;
33626
+ font-weight: 400;
33627
+ font-size: 16px;
33628
33628
  padding: 12px 24px;
33629
33629
  border-radius: 8px;
33630
33630
  border: none;
33631
- font-size: 16px;
33632
- font-weight: 500;
33633
33631
  cursor: pointer;
33634
33632
  transition: all 0.2s ease;
33635
33633
  display: flex;
33636
33634
  align-items: center;
33637
33635
  justify-content: center;
33638
- gap: 8px;
33639
33636
  }
33640
33637
 
33641
33638
  .button-primary {
@@ -33659,21 +33656,19 @@ SessionStartModal.styles = css`
33659
33656
 
33660
33657
  .close-button {
33661
33658
  position: absolute;
33662
- top: 16px;
33659
+ top: 12px;
33663
33660
  right: 16px;
33664
33661
  background: none;
33665
33662
  border: none;
33666
33663
  cursor: pointer;
33667
33664
  font-size: 24px;
33668
33665
  color: #6b7280;
33669
- padding: 4px;
33670
- border-radius: 4px;
33671
- transition: all 0.2s ease;
33672
- }
33673
-
33674
- .close-button:hover {
33675
- color: #374151;
33676
- background: #f3f4f6;
33666
+ padding: 0;
33667
+ margin: 0;
33668
+ line-height: 1;
33669
+ display: inline-flex;
33670
+ align-items: center;
33671
+ justify-content: center;
33677
33672
  }
33678
33673
  `;
33679
33674
  __decorateClass$1([
@@ -33699,7 +33694,6 @@ var __decorateClass = (decorators, target, key, kind) => {
33699
33694
  __defProp(target, key, result);
33700
33695
  return result;
33701
33696
  };
33702
- const WIDGET_PARAMS_KEY = "io.obi.widget-parameters";
33703
33697
  class ObiWidget extends LitElement {
33704
33698
  constructor() {
33705
33699
  super();
@@ -33751,6 +33745,7 @@ class ObiWidget extends LitElement {
33751
33745
  name: sessionWithPlan.onboarding_plan?.name || "",
33752
33746
  description: sessionWithPlan.onboarding_plan?.description || ""
33753
33747
  };
33748
+ this.state = SDKState.LOADING;
33754
33749
  this.showSessionStartModal = true;
33755
33750
  } else {
33756
33751
  console.log("No session found with token:", sessionToken);
@@ -33790,12 +33785,14 @@ class ObiWidget extends LitElement {
33790
33785
  removeSessionUrlParams() {
33791
33786
  const url = new URL(window.location.href);
33792
33787
  url.searchParams.delete(SESSION_URL_PARAM);
33793
- url.searchParams.delete(API_KEY_URL_PARAM);
33794
33788
  window.history.replaceState({}, "", url.toString());
33795
33789
  try {
33796
- localStorage.removeItem(WIDGET_PARAMS_KEY);
33790
+ if (window.__obiUrlParams) {
33791
+ ;
33792
+ window.__obiUrlParams = null;
33793
+ }
33797
33794
  } catch (error) {
33798
- console.warn("Failed to remove widget parameters from localStorage:", error);
33795
+ console.warn("Failed to clean up window URL parameters:", error);
33799
33796
  }
33800
33797
  }
33801
33798
  /**
@@ -33985,13 +33982,8 @@ class ObiWidget extends LitElement {
33985
33982
  await this.checkExistingSession();
33986
33983
  if (!this.activeSession) {
33987
33984
  let storedParams = {};
33988
- try {
33989
- const storedParamsJson = localStorage.getItem(WIDGET_PARAMS_KEY);
33990
- if (storedParamsJson) {
33991
- storedParams = JSON.parse(storedParamsJson);
33992
- }
33993
- } catch (error) {
33994
- console.warn("Failed to parse stored widget parameters:", error);
33985
+ if (window.__obiUrlParams) {
33986
+ storedParams = window.__obiUrlParams;
33995
33987
  }
33996
33988
  if (Object.keys(storedParams).length === 0) {
33997
33989
  const urlParams = new URLSearchParams(window.location.search);
@@ -34000,14 +33992,15 @@ class ObiWidget extends LitElement {
34000
33992
  });
34001
33993
  }
34002
33994
  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
33995
  if (sessionId && this.apiKey) {
34010
33996
  await this.handleUrlSessionEvent(sessionId);
33997
+ } else if (sessionId && !this.apiKey) {
33998
+ console.log("Session ID found but API key not ready, retrying...");
33999
+ setTimeout(() => {
34000
+ if (this.apiKey) {
34001
+ this.handleUrlSessionEvent(sessionId);
34002
+ }
34003
+ }, 100);
34011
34004
  }
34012
34005
  }
34013
34006
  }
@@ -34018,7 +34011,17 @@ class ObiWidget extends LitElement {
34018
34011
  this.boundSaveSessionData = this.saveSessionData.bind(this);
34019
34012
  window.addEventListener("beforeunload", this.boundSaveSessionData);
34020
34013
  window.addEventListener("pagehide", this.boundSaveSessionData);
34021
- this.sessionConnectionCheck();
34014
+ if (document.readyState === "complete") {
34015
+ Promise.resolve().then(() => this.sessionConnectionCheck());
34016
+ } else {
34017
+ window.addEventListener(
34018
+ "load",
34019
+ () => {
34020
+ Promise.resolve().then(() => this.sessionConnectionCheck());
34021
+ },
34022
+ { once: true }
34023
+ );
34024
+ }
34022
34025
  }
34023
34026
  disconnectedCallback() {
34024
34027
  if (this.closeNavTimeoutRef !== null) {
@@ -34133,6 +34136,8 @@ class ObiWidget extends LitElement {
34133
34136
  .onClose=${() => {
34134
34137
  this.showSessionStartModal = false;
34135
34138
  this.selectedCourse = null;
34139
+ this.state = SDKState.READY;
34140
+ this.removeSessionUrlParams();
34136
34141
  }}
34137
34142
  ></obi-session-start-modal>` : nothing}
34138
34143
  `;
@@ -34309,6 +34314,36 @@ if (!customElements.get("obi-widget")) {
34309
34314
  if (!customElements.get("obi-widget")) {
34310
34315
  customElements.define("obi-widget", ObiWidget);
34311
34316
  }
34317
+ const RETRY_CONFIG = {
34318
+ maxAttempts: 3,
34319
+ baseDelay: 200,
34320
+ // ms
34321
+ maxDelay: 2e3
34322
+ // ms
34323
+ };
34324
+ function delay(ms) {
34325
+ return new Promise((resolve) => setTimeout(resolve, ms));
34326
+ }
34327
+ function getRetryDelay(attempt) {
34328
+ const exponentialDelay = RETRY_CONFIG.baseDelay * Math.pow(2, attempt);
34329
+ return Math.min(exponentialDelay, RETRY_CONFIG.maxDelay);
34330
+ }
34331
+ async function retryOperation(operation, operationName, maxAttempts = RETRY_CONFIG.maxAttempts) {
34332
+ let lastError = null;
34333
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
34334
+ try {
34335
+ return await operation();
34336
+ } catch (error) {
34337
+ lastError = error;
34338
+ console.warn(`${operationName} failed (attempt ${attempt + 1}/${maxAttempts}):`, error);
34339
+ if (attempt < maxAttempts - 1) {
34340
+ const delayMs = getRetryDelay(attempt);
34341
+ await delay(delayMs);
34342
+ }
34343
+ }
34344
+ }
34345
+ throw new Error(`${operationName} failed after ${maxAttempts} attempts: ${lastError?.message}`);
34346
+ }
34312
34347
  function mountSDK() {
34313
34348
  const w2 = window;
34314
34349
  if (typeof w2.ObiSDK === "function" || typeof w2.ObiSDK === "object") {
@@ -34324,12 +34359,18 @@ function mountSDK() {
34324
34359
  };
34325
34360
  w2.ObiSDK.q = [];
34326
34361
  }
34327
- function mountWidget() {
34328
- if (!document.querySelector("obi-widget")) {
34362
+ async function mountWidget() {
34363
+ return retryOperation(async () => {
34364
+ if (document.querySelector("obi-widget")) {
34365
+ return;
34366
+ }
34367
+ if (!document.body) {
34368
+ throw new Error("document.body not available");
34369
+ }
34329
34370
  const widget = document.createElement("obi-widget");
34330
34371
  document.body.appendChild(widget);
34331
34372
  console.log("Obi Widget mounted");
34332
- }
34373
+ }, "Widget mounting");
34333
34374
  }
34334
34375
  function processQueue() {
34335
34376
  const w2 = window;
@@ -34346,17 +34387,62 @@ function processQueue() {
34346
34387
  w2.ObiSDK.q = [];
34347
34388
  }
34348
34389
  }
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);
34390
+ async function loadFonts() {
34391
+ await loadFont("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");
34392
+ await loadFont("https://fonts.cdnfonts.com/css/satoshi");
34393
+ }
34394
+ async function loadFont(fontUrl) {
34395
+ return retryOperation(async () => {
34396
+ if (!document.head) {
34397
+ throw new Error("document.head not available");
34398
+ }
34399
+ const link = document.createElement("link");
34400
+ document.head.querySelectorAll("link[data-obi-font]").forEach((node) => node.remove());
34401
+ link.setAttribute("data-obi-font", "true");
34402
+ link.href = fontUrl;
34403
+ link.rel = "stylesheet";
34404
+ return new Promise((resolve, reject) => {
34405
+ const timeout = setTimeout(() => {
34406
+ reject(new Error("Font loading timeout"));
34407
+ }, 5e3);
34408
+ link.onload = () => {
34409
+ clearTimeout(timeout);
34410
+ resolve();
34411
+ };
34412
+ link.onerror = () => {
34413
+ clearTimeout(timeout);
34414
+ reject(new Error("Font loading failed"));
34415
+ };
34416
+ document.head.appendChild(link);
34417
+ });
34418
+ }, "Font loading");
34419
+ }
34420
+ async function safeInitialize() {
34421
+ try {
34422
+ mountSDK();
34423
+ await loadFonts();
34424
+ await mountWidget();
34425
+ processQueue();
34426
+ console.log("Obi Widget initialized successfully");
34427
+ } catch (error) {
34428
+ console.error("Obi Widget initialization failed:", error);
34429
+ try {
34430
+ mountSDK();
34431
+ processQueue();
34432
+ console.log("Obi Widget fallback initialization completed");
34433
+ } catch (fallbackError) {
34434
+ console.error("Obi Widget fallback initialization failed:", fallbackError);
34435
+ }
34436
+ }
34354
34437
  }
34355
34438
  function initializeObiWidget() {
34356
- loadFonts();
34357
- mountSDK();
34358
- mountWidget();
34359
- processQueue();
34439
+ if (document.readyState === "loading") {
34440
+ document.addEventListener("DOMContentLoaded", () => {
34441
+ safeInitialize();
34442
+ });
34443
+ } else {
34444
+ safeInitialize();
34445
+ }
34360
34446
  }
34361
34447
  initializeObiWidget();
34362
34448
  export {