@deway-ai/web-sdk 0.72.0 → 0.73.0

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/dist/loader.es.js CHANGED
@@ -1,20 +1,81 @@
1
- const y = "deway-sdk-config", w = ["Understanding intent", "Reading web page", "Browsing the docs", "Enriching context", "Validating understanding", "Crafting response"];
2
- class S {
1
+ const I = {
2
+ debug: 0,
3
+ info: 1,
4
+ warn: 2,
5
+ error: 3
6
+ }, x = 4;
7
+ function L(o) {
8
+ if (typeof o == "bigint") return `${o}n`;
9
+ if (typeof o == "symbol") return o.toString();
10
+ if (typeof o == "function") return "[Function]";
11
+ }
12
+ function U(o, e) {
13
+ return o instanceof Error ? { name: o.name, message: o.message, stack: o.stack } : e.has(o) ? "[Circular]" : (e.add(o), o);
14
+ }
15
+ function _(o) {
16
+ const e = /* @__PURE__ */ new WeakSet();
17
+ return JSON.stringify(o, (t, n) => {
18
+ const i = L(n);
19
+ return i !== void 0 ? i : typeof n == "object" && n !== null ? U(n, e) : n;
20
+ });
21
+ }
22
+ function T(o, e) {
23
+ const t = o !== void 0 && Object.keys(o).length > 0, n = e !== void 0;
24
+ if (!t && !n) return;
25
+ const i = typeof e == "object" && e !== null && !Array.isArray(e) ? e : n ? { value: e } : {};
26
+ return { ...o, ...i };
27
+ }
28
+ function p(o, e, t, n, i) {
29
+ const r = e;
30
+ if (I[o] < r) return;
31
+ const s = {
32
+ level: o,
33
+ time: Date.now(),
34
+ msg: t
35
+ }, c = T(n, i);
36
+ c !== void 0 && (s.ctx = c), _(s);
37
+ }
38
+ function u(o) {
39
+ const e = o !== void 0 && "minLevel" in o ? o.minLevel : void 0, t = e === void 0 ? x : I[e], n = o?.context;
40
+ return {
41
+ debug(i, r) {
42
+ p("debug", t, i, n, r);
43
+ },
44
+ info(i, r) {
45
+ p("info", t, i, n, r);
46
+ },
47
+ warn(i, r) {
48
+ p("warn", t, i, n, r);
49
+ },
50
+ error(i, r) {
51
+ p("error", t, i, n, r);
52
+ },
53
+ child(i) {
54
+ return u({
55
+ minLevel: e,
56
+ context: { ...n, ...i }
57
+ });
58
+ }
59
+ };
60
+ }
61
+ const k = u({ context: { module: "sdk-config-store" } }), A = "deway-sdk-config", Q = ["Understanding intent", "Reading web page", "Browsing the docs", "Enriching context", "Validating understanding", "Crafting response"], N = 18;
62
+ class R {
3
63
  saveConfig(e) {
4
64
  if (window?.localStorage)
5
65
  try {
6
66
  const t = JSON.stringify(e);
7
- window.localStorage.setItem(y, t);
8
- } catch {
67
+ window.localStorage.setItem(A, t);
68
+ } catch (t) {
69
+ k.warn("Failed to save SDK config to localStorage", t);
9
70
  }
10
71
  }
11
72
  loadConfig() {
12
73
  if (window?.localStorage)
13
74
  try {
14
- const e = window.localStorage.getItem(y);
75
+ const e = window.localStorage.getItem(A);
15
76
  return e ? JSON.parse(e) : null;
16
- } catch {
17
- return null;
77
+ } catch (e) {
78
+ return k.warn("Failed to load SDK config from localStorage", e), null;
18
79
  }
19
80
  return null;
20
81
  }
@@ -28,7 +89,7 @@ class S {
28
89
  return this.loadConfig()?.aiDisclaimer;
29
90
  }
30
91
  getThinkingMessages() {
31
- return this.loadConfig()?.thinkingMessages ?? w;
92
+ return this.loadConfig()?.thinkingMessages ?? Q;
32
93
  }
33
94
  /**
34
95
  * Get the support handoff configuration
@@ -84,7 +145,7 @@ class S {
84
145
  return this.getCustomIcons()?.empty_chat_state_icon_inline_svg ?? void 0;
85
146
  }
86
147
  getEntrypointWidgetIconSize() {
87
- return this.loadConfig()?.entrypointWidgetIconSize ?? 18;
148
+ return this.loadConfig()?.entrypointWidgetIconSize ?? N;
88
149
  }
89
150
  getUIAlignment() {
90
151
  return this.loadConfig()?.uiAlignment ?? null;
@@ -96,106 +157,113 @@ class S {
96
157
  return this.getUIAlignment()?.side ?? "right";
97
158
  }
98
159
  }
99
- class c {
160
+ const f = u({ context: { module: "sdk-cache-manager" } });
161
+ class l {
100
162
  static CACHE_KEY = "deway-sdk-cache";
101
163
  static DB_NAME = "DewaySdk";
102
164
  static DB_VERSION = 1;
103
165
  static STORE_NAME = "sdk";
104
- async cacheSDK(e, t, i, n) {
166
+ async cacheSDK(e, t, n, i) {
105
167
  try {
106
- const d = (await this.openIndexedDB()).transaction([c.STORE_NAME], "readwrite").objectStore(c.STORE_NAME);
107
- await new Promise((h, m) => {
108
- const l = d.put({
168
+ const c = (await this.openIndexedDB()).transaction([l.STORE_NAME], "readwrite").objectStore(l.STORE_NAME);
169
+ await new Promise((E, K) => {
170
+ const g = c.put({
109
171
  id: "latest",
110
172
  code: e,
111
173
  version: t,
112
- checksum: i,
113
- signature: n,
174
+ checksum: n,
175
+ signature: i,
114
176
  timestamp: Date.now()
115
177
  });
116
- l.onsuccess = () => h(l.result), l.onerror = () => m(l.error);
117
- });
178
+ g.onsuccess = () => E(g.result), g.onerror = () => K(g.error);
179
+ }), f.debug("SDK cached in IndexedDB");
118
180
  } catch {
119
181
  try {
120
- const a = JSON.stringify({
182
+ const s = JSON.stringify({
121
183
  code: e,
122
184
  version: t,
123
- checksum: i,
124
- signature: n,
185
+ checksum: n,
186
+ signature: i,
125
187
  timestamp: Date.now()
126
188
  });
127
- localStorage.setItem(c.CACHE_KEY, a);
128
- } catch {
189
+ localStorage.setItem(l.CACHE_KEY, s), f.debug("SDK cached in localStorage");
190
+ } catch (s) {
191
+ f.warn("Unable to cache SDK", s);
129
192
  }
130
193
  }
131
194
  }
132
195
  async getCachedSDK() {
133
196
  try {
134
- const i = (await this.openIndexedDB()).transaction([c.STORE_NAME], "readonly").objectStore(c.STORE_NAME), n = await new Promise((r, a) => {
135
- const d = i.get("latest");
136
- d.onsuccess = () => r(d.result || null), d.onerror = () => a(d.error);
197
+ const n = (await this.openIndexedDB()).transaction([l.STORE_NAME], "readonly").objectStore(l.STORE_NAME), i = await new Promise((r, s) => {
198
+ const c = n.get("latest");
199
+ c.onsuccess = () => r(c.result || null), c.onerror = () => s(c.error);
137
200
  });
138
- if (n)
139
- return n;
201
+ if (i)
202
+ return f.debug("Found cached SDK in IndexedDB"), i;
140
203
  } catch {
204
+ f.debug("IndexedDB unavailable, trying localStorage");
141
205
  }
142
206
  try {
143
- const e = localStorage.getItem(c.CACHE_KEY);
207
+ const e = localStorage.getItem(l.CACHE_KEY);
144
208
  if (e)
145
- return JSON.parse(e);
146
- } catch {
209
+ return f.debug("Found cached SDK in localStorage"), JSON.parse(e);
210
+ } catch (e) {
211
+ f.warn("Failed to read from localStorage", e);
147
212
  }
148
213
  return null;
149
214
  }
150
215
  openIndexedDB() {
151
216
  return new Promise((e, t) => {
152
- const i = indexedDB.open(c.DB_NAME, c.DB_VERSION);
153
- i.onerror = () => t(i.error), i.onsuccess = () => e(i.result), i.onupgradeneeded = (n) => {
154
- const r = n.target.result;
155
- r.objectStoreNames.contains(c.STORE_NAME) || r.createObjectStore(c.STORE_NAME, { keyPath: "id" });
217
+ const n = indexedDB.open(l.DB_NAME, l.DB_VERSION);
218
+ n.onerror = () => t(n.error), n.onsuccess = () => e(n.result), n.onupgradeneeded = (i) => {
219
+ const r = i.target.result;
220
+ r.objectStoreNames.contains(l.STORE_NAME) || r.createObjectStore(l.STORE_NAME, { keyPath: "id" });
156
221
  };
157
222
  });
158
223
  }
159
224
  }
160
- async function C(o) {
161
- const t = new TextEncoder().encode(o), i = await crypto.subtle.digest("SHA-256", t);
162
- return Array.from(new Uint8Array(i)).map((r) => r.toString(16).padStart(2, "0")).join("");
225
+ const O = u({ context: { module: "sdk-verifier" } });
226
+ async function z(o) {
227
+ const t = new TextEncoder().encode(o), n = await crypto.subtle.digest("SHA-256", t);
228
+ return Array.from(new Uint8Array(n)).map((r) => r.toString(16).padStart(2, "0")).join("");
163
229
  }
164
- function p(o) {
230
+ function F(o) {
165
231
  const e = atob(o), t = new Uint8Array(e.length);
166
- for (let i = 0; i < e.length; i++)
167
- t[i] = e.charCodeAt(i);
232
+ for (let n = 0; n < e.length; n++)
233
+ t[n] = e.charCodeAt(n);
168
234
  return t;
169
235
  }
170
- function E(o) {
236
+ function $(o) {
171
237
  const e = new Uint8Array(o.length / 2);
172
238
  for (let t = 0; t < o.length; t += 2)
173
239
  e[t / 2] = Number.parseInt(o.substr(t, 2), 16);
174
240
  return e;
175
241
  }
176
- async function D(o, e, t) {
242
+ async function q(o, e, t) {
177
243
  try {
178
- const i = p(o), n = E(e), r = p(t), a = await crypto.subtle.importKey("raw", i, { name: "Ed25519" }, !1, ["verify"]);
179
- return await crypto.subtle.verify("Ed25519", a, r, n);
180
- } catch {
181
- return !1;
244
+ const n = F(o), i = $(e), r = F(t), s = await crypto.subtle.importKey("raw", n, { name: "Ed25519" }, !1, ["verify"]);
245
+ return await crypto.subtle.verify("Ed25519", s, r, i);
246
+ } catch (n) {
247
+ return O.error("Ed25519 signature verification failed", n), !1;
182
248
  }
183
249
  }
184
- async function A(o, e, t, i) {
250
+ async function P(o, e, t, n) {
185
251
  if (!e || !t)
186
252
  throw new Error("SDK verification failed: Missing security headers");
187
- if (await C(o) !== e)
253
+ if (await z(o) !== e)
188
254
  throw new Error("SDK verification failed: Checksum mismatch - content tampered");
189
- if (!await D(i, e, t))
255
+ if (!await q(n, e, t))
190
256
  throw new Error("SDK verification failed: Invalid signature - content tampered");
191
257
  }
192
- class b {
258
+ const m = u({ context: { module: "sdk-fetcher" } });
259
+ class V {
193
260
  cleanApiEndpoint(e) {
194
261
  return e.trim().replace(/\/+$/, "");
195
262
  }
196
- async fetchSDK(e, t, i) {
263
+ async fetchSDK(e, t, n) {
197
264
  try {
198
- const n = this.cleanApiEndpoint(t), r = await fetch(`${n}/sdk-serve/sdk/v0`, {
265
+ m.info("Fetching Deway SDK from backend...");
266
+ const i = this.cleanApiEndpoint(t), r = await fetch(`${i}/sdk-serve/sdk/v0`, {
199
267
  method: "GET",
200
268
  headers: {
201
269
  Accept: "application/javascript",
@@ -203,31 +271,38 @@ class b {
203
271
  Origin: window?.location?.origin || ""
204
272
  }
205
273
  });
206
- return r.ok ? this.handleSuccessfulFetch(r, i) : null;
207
- } catch {
208
- return null;
274
+ return r.ok ? this.handleSuccessfulFetch(r, n) : (m.warn(`Failed to fetch SDK: HTTP ${r.status}: ${r.statusText}`), null);
275
+ } catch (i) {
276
+ return m.warn("Failed to fetch SDK from server", i), null;
209
277
  }
210
278
  }
211
279
  async handleSuccessfulFetch(e, t) {
212
- const i = e.headers.get("x-sdk-checksum"), n = e.headers.get("x-sdk-version"), r = e.headers.get("x-sdk-signature"), a = await e.text();
213
- if (!n || !a || !i)
214
- throw Object.fromEntries(e.headers.entries()), new Error("Invalid SDK response: missing version, code, or checksum");
215
- return await A(a, i, r, t), { code: a, version: n, checksum: i, signature: r || "" };
280
+ const n = e.headers.get("x-sdk-checksum"), i = e.headers.get("x-sdk-version"), r = e.headers.get("x-sdk-signature"), s = await e.text();
281
+ if (m.info(`Fetched Deway SDK version ${i}`), !i || !s || !n) {
282
+ const c = Object.fromEntries(e.headers.entries());
283
+ throw m.error("Failed to get required data from sdk fetch", { headers: c }), new Error("Invalid SDK response: missing version, code, or checksum");
284
+ }
285
+ return await P(s, n, r, t), { code: s, version: i, checksum: n, signature: r || "" };
216
286
  }
217
287
  }
218
- class g {
288
+ const h = u({ context: { module: "command-queue" } });
289
+ class C {
219
290
  static MAX_QUEUE_SIZE = 50;
220
291
  commandQueue = [];
221
292
  queueCommand(e, ...t) {
222
- this.commandQueue.length >= g.MAX_QUEUE_SIZE && this.commandQueue.shift(), this.commandQueue.push({ method: e, args: t });
293
+ this.commandQueue.length >= C.MAX_QUEUE_SIZE && (h.warn(`Command queue full (${C.MAX_QUEUE_SIZE} commands). Discarding oldest command.`), this.commandQueue.shift()), this.commandQueue.push({ method: e, args: t }), h.debug(`Queued command: ${e} (queue size: ${this.commandQueue.length})`);
223
294
  }
224
295
  replayQueuedCommands() {
225
296
  if (this.commandQueue.length === 0)
226
297
  return;
298
+ h.info(`Replaying ${this.commandQueue.length} queued commands`);
227
299
  const e = [...this.commandQueue];
228
- if (this.commandQueue = [], !!this.isSDKAvailable())
229
- for (const t of e)
230
- this.replayCommand(t);
300
+ if (this.commandQueue = [], !this.isSDKAvailable()) {
301
+ h.warn("Deway SDK not available for command replay");
302
+ return;
303
+ }
304
+ for (const t of e)
305
+ this.replayCommand(t);
231
306
  }
232
307
  clearQueue() {
233
308
  this.commandQueue = [];
@@ -237,13 +312,15 @@ class g {
237
312
  }
238
313
  replayCommand(e) {
239
314
  try {
240
- const t = window.Deway, i = t?.[e.method];
241
- typeof i == "function" && i.apply(t, e.args);
242
- } catch {
315
+ const t = window.Deway, n = t?.[e.method];
316
+ typeof n == "function" ? n.apply(t, e.args) : h.warn(`Method ${e.method} not found on Deway SDK`);
317
+ } catch (t) {
318
+ h.error(`Failed to replay command ${e.method}`, t);
243
319
  }
244
320
  }
245
321
  }
246
- class u {
322
+ const w = u({ context: { module: "remote-config-cache" } });
323
+ class b {
247
324
  static CACHE_KEY = "deway-remote-config-cache";
248
325
  /**
249
326
  * Caches remote configuration in localStorage
@@ -254,13 +331,14 @@ class u {
254
331
  */
255
332
  async cacheRemoteConfig(e, t) {
256
333
  try {
257
- const i = {
334
+ const n = {
258
335
  config: e,
259
336
  ttl_seconds: t,
260
337
  timestamp: Date.now()
261
338
  };
262
- localStorage.setItem(u.CACHE_KEY, JSON.stringify(i));
263
- } catch {
339
+ localStorage.setItem(b.CACHE_KEY, JSON.stringify(n)), w.debug("Remote configuration cached in localStorage");
340
+ } catch (n) {
341
+ w.warn("Failed to cache remote config", n);
264
342
  }
265
343
  }
266
344
  /**
@@ -271,10 +349,13 @@ class u {
271
349
  */
272
350
  async getCachedRemoteConfig() {
273
351
  try {
274
- const e = localStorage.getItem(u.CACHE_KEY);
275
- return e ? JSON.parse(e) : null;
276
- } catch {
277
- return null;
352
+ const e = localStorage.getItem(b.CACHE_KEY);
353
+ if (!e)
354
+ return null;
355
+ const t = JSON.parse(e);
356
+ return w.debug("Found cached remote configuration"), t;
357
+ } catch (e) {
358
+ return w.warn("Failed to read cached remote config", e), null;
278
359
  }
279
360
  }
280
361
  /**
@@ -286,11 +367,12 @@ class u {
286
367
  * @returns true if cache is still valid
287
368
  */
288
369
  isCacheValid(e, t) {
289
- const i = Date.now(), n = e + t * 1e3;
290
- return i < n;
370
+ const n = Date.now(), i = e + t * 1e3;
371
+ return n < i;
291
372
  }
292
373
  }
293
- class v {
374
+ const S = u({ context: { module: "remote-config-fetcher" } });
375
+ class j {
294
376
  cleanApiEndpoint(e) {
295
377
  return e.trim().replace(/\/+$/, "");
296
378
  }
@@ -304,7 +386,8 @@ class v {
304
386
  */
305
387
  async fetchRemoteConfig(e, t) {
306
388
  try {
307
- const i = this.cleanApiEndpoint(t), n = await fetch(`${i}/sdk-remote-config-serve/`, {
389
+ S.info("Fetching remote configuration from backend...");
390
+ const n = this.cleanApiEndpoint(t), i = await fetch(`${n}/sdk-remote-config-serve/`, {
308
391
  method: "GET",
309
392
  headers: {
310
393
  Accept: "application/json",
@@ -312,33 +395,38 @@ class v {
312
395
  Origin: window?.location?.origin || ""
313
396
  }
314
397
  });
315
- return n.ok ? await n.json() : null;
316
- } catch {
317
- return null;
398
+ if (i.ok) {
399
+ const r = await i.json();
400
+ return S.info("Remote configuration fetched successfully"), r;
401
+ }
402
+ return S.warn(`Failed to fetch remote config: HTTP ${i.status}: ${i.statusText}`), null;
403
+ } catch (n) {
404
+ return S.warn("Failed to fetch remote config from server", n), null;
318
405
  }
319
406
  }
320
407
  }
321
- class I {
408
+ const y = u({ context: { module: "script-executor" } });
409
+ class H {
322
410
  async executeSDK(e) {
323
411
  return new Promise((t) => {
324
412
  try {
325
413
  if (!this.isDocumentReady()) {
326
- t(!1);
414
+ y.error("Document is not available for script execution"), t(!1);
327
415
  return;
328
416
  }
329
- const i = document.createElement("script");
330
- i.textContent = e, i.type = "text/javascript";
331
- let n = !1;
332
- const r = (a) => {
333
- n || (n = !0, this.cleanupScript(i), t(a));
417
+ const n = document.createElement("script");
418
+ n.textContent = e, n.type = "text/javascript";
419
+ let i = !1;
420
+ const r = (s) => {
421
+ i || (i = !0, this.cleanupScript(n), t(s));
334
422
  };
335
- i.onerror = () => {
336
- r(!1);
337
- }, i.onload = () => r(!0), document.head.appendChild(i), setTimeout(() => {
338
- !n && this.verifySDKLoaded() ? r(!0) : n || r(!1);
423
+ n.onerror = () => {
424
+ y.error("Script execution failed"), r(!1);
425
+ }, n.onload = () => r(!0), document.head.appendChild(n), setTimeout(() => {
426
+ !i && this.verifySDKLoaded() ? r(!0) : i || (y.error("SDK execution timeout - Deway object not found"), r(!1));
339
427
  }, 100);
340
- } catch {
341
- t(!1);
428
+ } catch (n) {
429
+ y.error("Failed to execute SDK script", n), t(!1);
342
430
  }
343
431
  });
344
432
  }
@@ -351,13 +439,15 @@ class I {
351
439
  cleanupScript(e) {
352
440
  try {
353
441
  e.parentNode && e.parentNode.removeChild(e);
354
- } catch {
442
+ } catch (t) {
443
+ y.debug("Failed to cleanup script element", t);
355
444
  }
356
445
  }
357
446
  }
358
- class K {
447
+ const D = u({ context: { module: "config-validator" } });
448
+ class M {
359
449
  validateConfig(e) {
360
- return !(!e || !e.appKey || e.appKey.trim().length === 0 || e.apiEndpoint !== void 0 && !this.isValidUrl(e.apiEndpoint) || e.publicKey !== void 0 && e.publicKey.trim().length === 0);
450
+ return e ? !e.appKey || e.appKey.trim().length === 0 ? (D.error("Config.appKey is required and must be a non-empty string"), !1) : e.apiEndpoint !== void 0 && !this.isValidUrl(e.apiEndpoint) ? (D.error("Config.apiEndpoint must be a valid URL"), !1) : e.publicKey !== void 0 && e.publicKey.trim().length === 0 ? (D.error("Config.publicKey must be a non-empty string if provided"), !1) : !0 : (D.error("Config is required"), !1);
361
451
  }
362
452
  isValidUrl(e) {
363
453
  try {
@@ -367,11 +457,11 @@ class K {
367
457
  }
368
458
  }
369
459
  }
370
- const f = {
460
+ const a = u({ context: { module: "sdk-loader" } }), v = {
371
461
  apiEndpoint: "https://service.deway.app",
372
462
  publicKey: "9d3dBUvqyUQ7egd5j5uORdHSqZ7VFWOu+ud/SWt9WUY="
373
463
  };
374
- class k {
464
+ class B {
375
465
  isLoaded = !1;
376
466
  isLoading = !1;
377
467
  cacheManager;
@@ -383,25 +473,32 @@ class k {
383
473
  remoteConfigCache;
384
474
  sdkConfigStore;
385
475
  constructor() {
386
- this.cacheManager = new c(), this.scriptExecutor = new I(), this.commandQueue = new g(), this.sdkFetcher = new b(), this.configValidator = new K(), this.sdkConfigStore = new S(), this.remoteConfigFetcher = new v(), this.remoteConfigCache = new u();
476
+ this.cacheManager = new l(), this.scriptExecutor = new H(), this.commandQueue = new C(), this.sdkFetcher = new V(), this.configValidator = new M(), this.sdkConfigStore = new R(), this.remoteConfigFetcher = new j(), this.remoteConfigCache = new b();
387
477
  }
388
478
  init(e) {
389
479
  this.performInit(e).catch((t) => {
480
+ a.error("Failed to initialize Deway SDK", t);
390
481
  });
391
482
  }
392
483
  async performInit(e) {
393
484
  try {
394
485
  if (!this.canInitialize())
395
486
  return;
396
- const t = this.isInitializationPayload(e), i = t ? e.localConfig : e;
397
- if (!this.configValidator.validateConfig(i))
487
+ const t = this.isInitializationPayload(e), n = t ? e.localConfig : e;
488
+ if (!this.configValidator.validateConfig(n)) {
489
+ a.error("Invalid config provided to Deway SDK");
398
490
  return;
491
+ }
399
492
  this.isLoading = !0;
400
- const n = i.apiEndpoint || f.apiEndpoint, r = i.publicKey || f.publicKey, [a, d] = await Promise.all([this.fetchOrLoadSDK(i.appKey, n, r), this.fetchRemoteConfigWithCache(i, n)]);
401
- if (!a)
493
+ const i = n.apiEndpoint || v.apiEndpoint, r = n.publicKey || v.publicKey, [s, c] = await Promise.all([this.fetchOrLoadSDK(n.appKey, i, r), this.fetchRemoteConfigWithCache(n, i)]);
494
+ if (!s)
402
495
  return;
403
- const h = t ? e : this.createInitializationPayload(d, i);
404
- if (!await this.scriptExecutor.executeSDK(a.code) || !this.initializeSDK(h))
496
+ const E = t ? e : this.createInitializationPayload(c, n);
497
+ if (!await this.scriptExecutor.executeSDK(s.code)) {
498
+ a.error("SDK execution failed");
499
+ return;
500
+ }
501
+ if (!this.initializeSDK(E))
405
502
  return;
406
503
  this.commandQueue.replayQueuedCommands(), this.isLoaded = !0;
407
504
  } finally {
@@ -412,7 +509,7 @@ class k {
412
509
  return "localConfig" in e && "remoteConfig" in e && "defaults" in e;
413
510
  }
414
511
  canInitialize() {
415
- return !(this.isLoaded || this.isLoading);
512
+ return this.isLoaded ? (a.warn("Deway SDK already initialized"), !1) : this.isLoading ? (a.warn("Deway SDK initialization already in progress"), !1) : !0;
416
513
  }
417
514
  /**
418
515
  * Fetches remote config from backend with cache fallback
@@ -420,14 +517,15 @@ class k {
420
517
  */
421
518
  async fetchRemoteConfigWithCache(e, t) {
422
519
  this.sdkConfigStore.saveConfig(e);
423
- const i = await this.remoteConfigFetcher.fetchRemoteConfig(e.appKey, t);
424
- if (i)
425
- return await this.remoteConfigCache.cacheRemoteConfig(i.config, i.ttl_seconds), i;
426
- const n = await this.remoteConfigCache.getCachedRemoteConfig();
427
- return n ? {
428
- config: n.config,
429
- ttl_seconds: n.ttl_seconds
430
- } : null;
520
+ const n = await this.remoteConfigFetcher.fetchRemoteConfig(e.appKey, t);
521
+ if (n)
522
+ return await this.remoteConfigCache.cacheRemoteConfig(n.config, n.ttl_seconds), n;
523
+ a.info("Using cached remote config as fallback");
524
+ const i = await this.remoteConfigCache.getCachedRemoteConfig();
525
+ return i ? {
526
+ config: i.config,
527
+ ttl_seconds: i.ttl_seconds
528
+ } : (a.warn("No remote config available (fetch failed and no cache)"), null);
431
529
  }
432
530
  /**
433
531
  * Creates initialization payload for backend SDK (NEW LOADER v0.29.0+)
@@ -438,120 +536,130 @@ class k {
438
536
  return {
439
537
  localConfig: t,
440
538
  remoteConfig: e?.config ?? null,
441
- defaults: f
539
+ defaults: v
442
540
  };
443
541
  }
444
- async fetchOrLoadSDK(e, t, i) {
445
- const n = await this.sdkFetcher.fetchSDK(e, t, i);
446
- return n ? (await this.cacheManager.cacheSDK(n.code, n.version, n.checksum, n.signature), n) : this.loadFromCache();
542
+ async fetchOrLoadSDK(e, t, n) {
543
+ const i = await this.sdkFetcher.fetchSDK(e, t, n);
544
+ return i ? (await this.cacheManager.cacheSDK(i.code, i.version, i.checksum, i.signature), i) : (a.warn("Failed to fetch SDK from server, attempting cache fallback"), this.loadFromCache());
447
545
  }
448
546
  async loadFromCache() {
449
547
  const e = await this.cacheManager.getCachedSDK();
450
- return e ? { code: e.code, version: e.version } : null;
548
+ return e ? (a.info(`Loading cached Deway SDK version ${e.version}`), { code: e.code, version: e.version }) : (a.error("SDK unavailable: Network error and no cached version found"), null);
451
549
  }
452
550
  initializeSDK(e) {
453
551
  if (!this.isSDKAvailable())
454
- return !1;
552
+ return a.error("SDK execution failed: Deway object not found after loading"), !1;
455
553
  try {
456
- return window.Deway?.init(e), !0;
457
- } catch {
458
- return !1;
554
+ return window.Deway?.init(e), a.info("Deway SDK initialized successfully with payload"), !0;
555
+ } catch (t) {
556
+ return a.error("Failed to initialize SDK with payload", t), !1;
459
557
  }
460
558
  }
461
559
  identify(e) {
462
560
  try {
463
561
  this.isLoaded && this.isSDKAvailable() ? window.Deway?.identify(e) : this.commandQueue.queueCommand("identify", e);
464
- } catch {
562
+ } catch (t) {
563
+ a.error("Failed to identify user", t);
465
564
  }
466
565
  }
467
566
  reportEvent(e, t) {
468
567
  try {
469
568
  this.isLoaded && this.isSDKAvailable() ? window.Deway?.reportEvent(e, t) : this.commandQueue.queueCommand("reportEvent", e, t);
470
- } catch {
569
+ } catch (n) {
570
+ a.error("Failed to report event", n);
471
571
  }
472
572
  }
473
573
  setUserProfile(e) {
474
574
  try {
475
575
  this.isLoaded && this.isSDKAvailable() ? window.Deway?.setUserProfile(e) : this.commandQueue.queueCommand("setUserProfile", e);
476
- } catch {
576
+ } catch (t) {
577
+ a.error("Failed to set user profile", t);
477
578
  }
478
579
  }
479
580
  show(e) {
480
581
  try {
481
582
  this.isLoaded && this.isSDKAvailable() ? window.Deway?.show(e) : this.commandQueue.queueCommand("show", e);
482
- } catch {
583
+ } catch (t) {
584
+ a.error("Failed to show bookmark", t);
483
585
  }
484
586
  }
485
587
  hide() {
486
588
  try {
487
589
  this.isLoaded && this.isSDKAvailable() ? window.Deway?.hide() : this.commandQueue.queueCommand("hide");
488
- } catch {
590
+ } catch (e) {
591
+ a.error("Failed to hide bookmark", e);
489
592
  }
490
593
  }
491
594
  openChat() {
492
595
  try {
493
596
  this.isLoaded && this.isSDKAvailable() ? window.Deway?.openChat() : this.commandQueue.queueCommand("openChat");
494
- } catch {
597
+ } catch (e) {
598
+ a.error("Failed to open chat", e);
495
599
  }
496
600
  }
497
601
  resetUserLocally() {
498
602
  try {
499
603
  this.isLoaded && this.isSDKAvailable() ? window.Deway?.resetUserLocally() : this.commandQueue.queueCommand("resetUserLocally");
500
- } catch {
604
+ } catch (e) {
605
+ a.error("Failed to reset user locally", e);
501
606
  }
502
607
  }
503
608
  isVisible() {
504
609
  try {
505
610
  return this.isLoaded && this.isSDKAvailable() ? window.Deway?.isVisible() ?? !1 : !1;
506
- } catch {
507
- return !1;
611
+ } catch (e) {
612
+ return a.error("Failed to check bookmark visibility", e), !1;
508
613
  }
509
614
  }
510
615
  isInitialized() {
511
616
  try {
512
617
  return this.isLoaded && this.isSDKAvailable() ? window.Deway?.isInitialized() ?? !1 : !1;
513
- } catch {
514
- return !1;
618
+ } catch (e) {
619
+ return a.error("Failed to check initialization status", e), !1;
515
620
  }
516
621
  }
517
622
  registerSupportCallback(e) {
518
623
  try {
519
624
  this.isLoaded && this.isSDKAvailable() ? window.Deway?.registerSupportCallback(e) : this.commandQueue.queueCommand("registerSupportCallback", e);
520
- } catch {
625
+ } catch (t) {
626
+ a.error("Failed to register support callback", t);
521
627
  }
522
628
  }
523
629
  unregisterSupportCallback() {
524
630
  try {
525
631
  this.isLoaded && this.isSDKAvailable() ? window.Deway?.unregisterSupportCallback() : this.commandQueue.queueCommand("unregisterSupportCallback");
526
- } catch {
632
+ } catch (e) {
633
+ a.error("Failed to unregister support callback", e);
527
634
  }
528
635
  }
529
636
  destroy() {
530
637
  try {
531
638
  this.isLoaded && this.isSDKAvailable() ? window.Deway?.destroy() : this.commandQueue.queueCommand("destroy"), this.commandQueue.clearQueue();
532
- } catch {
639
+ } catch (e) {
640
+ a.error("Failed to destroy SDK", e);
533
641
  }
534
642
  }
535
643
  isSDKAvailable() {
536
644
  return typeof window < "u" && "Deway" in window && !!window.Deway;
537
645
  }
538
646
  }
539
- const s = new k(), _ = {
540
- init: (o) => s.init(o),
541
- identify: (o) => s.identify(o),
542
- reportEvent: (o, e) => s.reportEvent(o, e),
543
- setUserProfile: (o) => s.setUserProfile(o),
544
- show: (o) => s.show(o),
545
- hide: () => s.hide(),
546
- openChat: () => s.openChat(),
547
- resetUserLocally: () => s.resetUserLocally(),
548
- registerSupportCallback: (o) => s.registerSupportCallback(o),
549
- unregisterSupportCallback: () => s.unregisterSupportCallback(),
550
- isVisible: () => s.isVisible(),
551
- isInitialized: () => s.isInitialized(),
552
- destroy: () => s.destroy()
647
+ const d = new B(), W = {
648
+ init: (o) => d.init(o),
649
+ identify: (o) => d.identify(o),
650
+ reportEvent: (o, e) => d.reportEvent(o, e),
651
+ setUserProfile: (o) => d.setUserProfile(o),
652
+ show: (o) => d.show(o),
653
+ hide: () => d.hide(),
654
+ openChat: () => d.openChat(),
655
+ resetUserLocally: () => d.resetUserLocally(),
656
+ registerSupportCallback: (o) => d.registerSupportCallback(o),
657
+ unregisterSupportCallback: () => d.unregisterSupportCallback(),
658
+ isVisible: () => d.isVisible(),
659
+ isInitialized: () => d.isInitialized(),
660
+ destroy: () => d.destroy()
553
661
  };
554
- typeof window < "u" && (window.Deway = _);
662
+ typeof window < "u" && (window.Deway = W);
555
663
  export {
556
- _ as default
664
+ W as default
557
665
  };
@@ -1 +1 @@
1
- (function(l,u){typeof exports=="object"&&typeof module<"u"?module.exports=u():typeof define=="function"&&define.amd?define(u):(l=typeof globalThis<"u"?globalThis:l||self,l.Deway=u())})(this,(function(){"use strict";const l="deway-sdk-config",u=["Understanding intent","Reading web page","Browsing the docs","Enriching context","Validating understanding","Crafting response"];class C{saveConfig(e){if(window?.localStorage)try{const t=JSON.stringify(e);window.localStorage.setItem(l,t)}catch{}}loadConfig(){if(window?.localStorage)try{const e=window.localStorage.getItem(l);return e?JSON.parse(e):null}catch{return null}return null}getExcludedVendors(){return this.loadConfig()?.excludedVendors??[]}getAssistantName(){return this.loadConfig()?.assistantName??"Assistant"}getAiDisclaimer(){return this.loadConfig()?.aiDisclaimer}getThinkingMessages(){return this.loadConfig()?.thinkingMessages??u}getSupportHandoff(){return this.loadConfig()?.supportHandoff??null}getSupportHandoffButtonText(){return this.getSupportHandoff()?.button_text??"talk to Support"}getFeatureFlags(){return this.loadConfig()?.featureFlags??{}}getFeatureFlag(e){return this.getFeatureFlags()[e]??!1}getPromptSuggestions(){return this.loadConfig()?.promptSuggestions}getWelcomeTitle(){return this.loadConfig()?.welcomeTitle??"How can I help you today?"}getWelcomeSubtitle(){return this.loadConfig()?.welcomeSubtitle??"I'm ready to help you navigate, learn, and get things done."}getEntrypointWidgetAppearanceMode(){return this.loadConfig()?.entrypointWidgetAppearanceMode??"bookmark"}getTenantTheme(){return this.loadConfig()?.tenantTheme??null}getTenantThemeForMode(e){const t=this.getTenantTheme();return t?e==="dark"?t.dark:t.light:null}getCustomIcons(){return this.loadConfig()?.customIcons??null}getEntrypointWidgetIconInlineSvg(){return this.getCustomIcons()?.entrypoint_widget_icon_inline_svg??void 0}getEmptyChatStateIconInlineSvg(){return this.getCustomIcons()?.empty_chat_state_icon_inline_svg??void 0}getEntrypointWidgetIconSize(){return this.loadConfig()?.entrypointWidgetIconSize??18}getUIAlignment(){return this.loadConfig()?.uiAlignment??null}getUIAlignmentAnchorSelector(){return this.getUIAlignment()?.anchor_selector??null}getUIAlignmentSide(){return this.getUIAlignment()?.side??"right"}}class c{static CACHE_KEY="deway-sdk-cache";static DB_NAME="DewaySdk";static DB_VERSION=1;static STORE_NAME="sdk";async cacheSDK(e,t,n,i){try{const d=(await this.openIndexedDB()).transaction([c.STORE_NAME],"readwrite").objectStore(c.STORE_NAME);await new Promise((y,S)=>{const h=d.put({id:"latest",code:e,version:t,checksum:n,signature:i,timestamp:Date.now()});h.onsuccess=()=>y(h.result),h.onerror=()=>S(h.error)})}catch{try{const a=JSON.stringify({code:e,version:t,checksum:n,signature:i,timestamp:Date.now()});localStorage.setItem(c.CACHE_KEY,a)}catch{}}}async getCachedSDK(){try{const n=(await this.openIndexedDB()).transaction([c.STORE_NAME],"readonly").objectStore(c.STORE_NAME),i=await new Promise((r,a)=>{const d=n.get("latest");d.onsuccess=()=>r(d.result||null),d.onerror=()=>a(d.error)});if(i)return i}catch{}try{const e=localStorage.getItem(c.CACHE_KEY);if(e)return JSON.parse(e)}catch{}return null}openIndexedDB(){return new Promise((e,t)=>{const n=indexedDB.open(c.DB_NAME,c.DB_VERSION);n.onerror=()=>t(n.error),n.onsuccess=()=>e(n.result),n.onupgradeneeded=i=>{const r=i.target.result;r.objectStoreNames.contains(c.STORE_NAME)||r.createObjectStore(c.STORE_NAME,{keyPath:"id"})}})}}async function E(o){const t=new TextEncoder().encode(o),n=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(n)).map(r=>r.toString(16).padStart(2,"0")).join("")}function p(o){const e=atob(o),t=new Uint8Array(e.length);for(let n=0;n<e.length;n++)t[n]=e.charCodeAt(n);return t}function D(o){const e=new Uint8Array(o.length/2);for(let t=0;t<o.length;t+=2)e[t/2]=Number.parseInt(o.substr(t,2),16);return e}async function A(o,e,t){try{const n=p(o),i=D(e),r=p(t),a=await crypto.subtle.importKey("raw",n,{name:"Ed25519"},!1,["verify"]);return await crypto.subtle.verify("Ed25519",a,r,i)}catch{return!1}}async function b(o,e,t,n){if(!e||!t)throw new Error("SDK verification failed: Missing security headers");if(await E(o)!==e)throw new Error("SDK verification failed: Checksum mismatch - content tampered");if(!await A(n,e,t))throw new Error("SDK verification failed: Invalid signature - content tampered")}class v{cleanApiEndpoint(e){return e.trim().replace(/\/+$/,"")}async fetchSDK(e,t,n){try{const i=this.cleanApiEndpoint(t),r=await fetch(`${i}/sdk-serve/sdk/v0`,{method:"GET",headers:{Accept:"application/javascript","deway-app-key":e,Origin:window?.location?.origin||""}});return r.ok?this.handleSuccessfulFetch(r,n):null}catch{return null}}async handleSuccessfulFetch(e,t){const n=e.headers.get("x-sdk-checksum"),i=e.headers.get("x-sdk-version"),r=e.headers.get("x-sdk-signature"),a=await e.text();if(!i||!a||!n)throw Object.fromEntries(e.headers.entries()),new Error("Invalid SDK response: missing version, code, or checksum");return await b(a,n,r,t),{code:a,version:i,checksum:n,signature:r||""}}}class g{static MAX_QUEUE_SIZE=50;commandQueue=[];queueCommand(e,...t){this.commandQueue.length>=g.MAX_QUEUE_SIZE&&this.commandQueue.shift(),this.commandQueue.push({method:e,args:t})}replayQueuedCommands(){if(this.commandQueue.length===0)return;const e=[...this.commandQueue];if(this.commandQueue=[],!!this.isSDKAvailable())for(const t of e)this.replayCommand(t)}clearQueue(){this.commandQueue=[]}isSDKAvailable(){return typeof window<"u"&&"Deway"in window&&!!window.Deway}replayCommand(e){try{const t=window.Deway,n=t?.[e.method];typeof n=="function"&&n.apply(t,e.args)}catch{}}}class f{static CACHE_KEY="deway-remote-config-cache";async cacheRemoteConfig(e,t){try{const n={config:e,ttl_seconds:t,timestamp:Date.now()};localStorage.setItem(f.CACHE_KEY,JSON.stringify(n))}catch{}}async getCachedRemoteConfig(){try{const e=localStorage.getItem(f.CACHE_KEY);return e?JSON.parse(e):null}catch{return null}}isCacheValid(e,t){const n=Date.now(),i=e+t*1e3;return n<i}}class I{cleanApiEndpoint(e){return e.trim().replace(/\/+$/,"")}async fetchRemoteConfig(e,t){try{const n=this.cleanApiEndpoint(t),i=await fetch(`${n}/sdk-remote-config-serve/`,{method:"GET",headers:{Accept:"application/json","deway-app-key":e,Origin:window?.location?.origin||""}});return i.ok?await i.json():null}catch{return null}}}class K{async executeSDK(e){return new Promise(t=>{try{if(!this.isDocumentReady()){t(!1);return}const n=document.createElement("script");n.textContent=e,n.type="text/javascript";let i=!1;const r=a=>{i||(i=!0,this.cleanupScript(n),t(a))};n.onerror=()=>{r(!1)},n.onload=()=>r(!0),document.head.appendChild(n),setTimeout(()=>{!i&&this.verifySDKLoaded()?r(!0):i||r(!1)},100)}catch{t(!1)}})}isDocumentReady(){return typeof document<"u"&&document.head!=null}verifySDKLoaded(){return typeof window<"u"&&"Deway"in window&&!!window.Deway}cleanupScript(e){try{e.parentNode&&e.parentNode.removeChild(e)}catch{}}}class k{validateConfig(e){return!(!e||!e.appKey||e.appKey.trim().length===0||e.apiEndpoint!==void 0&&!this.isValidUrl(e.apiEndpoint)||e.publicKey!==void 0&&e.publicKey.trim().length===0)}isValidUrl(e){try{return new URL(e),!0}catch{return!1}}}const m={apiEndpoint:"https://service.deway.app",publicKey:"9d3dBUvqyUQ7egd5j5uORdHSqZ7VFWOu+ud/SWt9WUY="};class _{isLoaded=!1;isLoading=!1;cacheManager;scriptExecutor;commandQueue;sdkFetcher;configValidator;remoteConfigFetcher;remoteConfigCache;sdkConfigStore;constructor(){this.cacheManager=new c,this.scriptExecutor=new K,this.commandQueue=new g,this.sdkFetcher=new v,this.configValidator=new k,this.sdkConfigStore=new C,this.remoteConfigFetcher=new I,this.remoteConfigCache=new f}init(e){this.performInit(e).catch(t=>{})}async performInit(e){try{if(!this.canInitialize())return;const t=this.isInitializationPayload(e),n=t?e.localConfig:e;if(!this.configValidator.validateConfig(n))return;this.isLoading=!0;const i=n.apiEndpoint||m.apiEndpoint,r=n.publicKey||m.publicKey,[a,d]=await Promise.all([this.fetchOrLoadSDK(n.appKey,i,r),this.fetchRemoteConfigWithCache(n,i)]);if(!a)return;const y=t?e:this.createInitializationPayload(d,n);if(!await this.scriptExecutor.executeSDK(a.code)||!this.initializeSDK(y))return;this.commandQueue.replayQueuedCommands(),this.isLoaded=!0}finally{this.isLoading=!1}}isInitializationPayload(e){return"localConfig"in e&&"remoteConfig"in e&&"defaults"in e}canInitialize(){return!(this.isLoaded||this.isLoading)}async fetchRemoteConfigWithCache(e,t){this.sdkConfigStore.saveConfig(e);const n=await this.remoteConfigFetcher.fetchRemoteConfig(e.appKey,t);if(n)return await this.remoteConfigCache.cacheRemoteConfig(n.config,n.ttl_seconds),n;const i=await this.remoteConfigCache.getCachedRemoteConfig();return i?{config:i.config,ttl_seconds:i.ttl_seconds}:null}createInitializationPayload(e,t){return{localConfig:t,remoteConfig:e?.config??null,defaults:m}}async fetchOrLoadSDK(e,t,n){const i=await this.sdkFetcher.fetchSDK(e,t,n);return i?(await this.cacheManager.cacheSDK(i.code,i.version,i.checksum,i.signature),i):this.loadFromCache()}async loadFromCache(){const e=await this.cacheManager.getCachedSDK();return e?{code:e.code,version:e.version}:null}initializeSDK(e){if(!this.isSDKAvailable())return!1;try{return window.Deway?.init(e),!0}catch{return!1}}identify(e){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.identify(e):this.commandQueue.queueCommand("identify",e)}catch{}}reportEvent(e,t){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.reportEvent(e,t):this.commandQueue.queueCommand("reportEvent",e,t)}catch{}}setUserProfile(e){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.setUserProfile(e):this.commandQueue.queueCommand("setUserProfile",e)}catch{}}show(e){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.show(e):this.commandQueue.queueCommand("show",e)}catch{}}hide(){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.hide():this.commandQueue.queueCommand("hide")}catch{}}openChat(){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.openChat():this.commandQueue.queueCommand("openChat")}catch{}}resetUserLocally(){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.resetUserLocally():this.commandQueue.queueCommand("resetUserLocally")}catch{}}isVisible(){try{return this.isLoaded&&this.isSDKAvailable()?window.Deway?.isVisible()??!1:!1}catch{return!1}}isInitialized(){try{return this.isLoaded&&this.isSDKAvailable()?window.Deway?.isInitialized()??!1:!1}catch{return!1}}registerSupportCallback(e){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.registerSupportCallback(e):this.commandQueue.queueCommand("registerSupportCallback",e)}catch{}}unregisterSupportCallback(){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.unregisterSupportCallback():this.commandQueue.queueCommand("unregisterSupportCallback")}catch{}}destroy(){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.destroy():this.commandQueue.queueCommand("destroy"),this.commandQueue.clearQueue()}catch{}}isSDKAvailable(){return typeof window<"u"&&"Deway"in window&&!!window.Deway}}const s=new _,w={init:o=>s.init(o),identify:o=>s.identify(o),reportEvent:(o,e)=>s.reportEvent(o,e),setUserProfile:o=>s.setUserProfile(o),show:o=>s.show(o),hide:()=>s.hide(),openChat:()=>s.openChat(),resetUserLocally:()=>s.resetUserLocally(),registerSupportCallback:o=>s.registerSupportCallback(o),unregisterSupportCallback:()=>s.unregisterSupportCallback(),isVisible:()=>s.isVisible(),isInitialized:()=>s.isInitialized(),destroy:()=>s.destroy()};return typeof window<"u"&&(window.Deway=w),w}));
1
+ (function(h,m){typeof exports=="object"&&typeof module<"u"?module.exports=m():typeof define=="function"&&define.amd?define(m):(h=typeof globalThis<"u"?globalThis:h||self,h.Deway=m())})(this,(function(){"use strict";const h={debug:0,info:1,warn:2,error:3},m=4;function U(o){if(typeof o=="bigint")return`${o}n`;if(typeof o=="symbol")return o.toString();if(typeof o=="function")return"[Function]"}function T(o,e){return o instanceof Error?{name:o.name,message:o.message,stack:o.stack}:e.has(o)?"[Circular]":(e.add(o),o)}function _(o){const e=new WeakSet;return JSON.stringify(o,(t,n)=>{const i=U(n);return i!==void 0?i:typeof n=="object"&&n!==null?T(n,e):n})}function Q(o,e){const t=o!==void 0&&Object.keys(o).length>0,n=e!==void 0;if(!t&&!n)return;const i=typeof e=="object"&&e!==null&&!Array.isArray(e)?e:n?{value:e}:{};return{...o,...i}}function S(o,e,t,n,i){const r=e;if(h[o]<r)return;const s={level:o,time:Date.now(),msg:t},d=Q(n,i);d!==void 0&&(s.ctx=d),_(s)}function u(o){const e=o!==void 0&&"minLevel"in o?o.minLevel:void 0,t=e===void 0?m:h[e],n=o?.context;return{debug(i,r){S("debug",t,i,n,r)},info(i,r){S("info",t,i,n,r)},warn(i,r){S("warn",t,i,n,r)},error(i,r){S("error",t,i,n,r)},child(i){return u({minLevel:e,context:{...n,...i}})}}}const A=u({context:{module:"sdk-config-store"}}),F="deway-sdk-config",N=["Understanding intent","Reading web page","Browsing the docs","Enriching context","Validating understanding","Crafting response"],R=18;class O{saveConfig(e){if(window?.localStorage)try{const t=JSON.stringify(e);window.localStorage.setItem(F,t)}catch(t){A.warn("Failed to save SDK config to localStorage",t)}}loadConfig(){if(window?.localStorage)try{const e=window.localStorage.getItem(F);return e?JSON.parse(e):null}catch(e){return A.warn("Failed to load SDK config from localStorage",e),null}return null}getExcludedVendors(){return this.loadConfig()?.excludedVendors??[]}getAssistantName(){return this.loadConfig()?.assistantName??"Assistant"}getAiDisclaimer(){return this.loadConfig()?.aiDisclaimer}getThinkingMessages(){return this.loadConfig()?.thinkingMessages??N}getSupportHandoff(){return this.loadConfig()?.supportHandoff??null}getSupportHandoffButtonText(){return this.getSupportHandoff()?.button_text??"talk to Support"}getFeatureFlags(){return this.loadConfig()?.featureFlags??{}}getFeatureFlag(e){return this.getFeatureFlags()[e]??!1}getPromptSuggestions(){return this.loadConfig()?.promptSuggestions}getWelcomeTitle(){return this.loadConfig()?.welcomeTitle??"How can I help you today?"}getWelcomeSubtitle(){return this.loadConfig()?.welcomeSubtitle??"I'm ready to help you navigate, learn, and get things done."}getEntrypointWidgetAppearanceMode(){return this.loadConfig()?.entrypointWidgetAppearanceMode??"bookmark"}getTenantTheme(){return this.loadConfig()?.tenantTheme??null}getTenantThemeForMode(e){const t=this.getTenantTheme();return t?e==="dark"?t.dark:t.light:null}getCustomIcons(){return this.loadConfig()?.customIcons??null}getEntrypointWidgetIconInlineSvg(){return this.getCustomIcons()?.entrypoint_widget_icon_inline_svg??void 0}getEmptyChatStateIconInlineSvg(){return this.getCustomIcons()?.empty_chat_state_icon_inline_svg??void 0}getEntrypointWidgetIconSize(){return this.loadConfig()?.entrypointWidgetIconSize??R}getUIAlignment(){return this.loadConfig()?.uiAlignment??null}getUIAlignmentAnchorSelector(){return this.getUIAlignment()?.anchor_selector??null}getUIAlignmentSide(){return this.getUIAlignment()?.side??"right"}}const f=u({context:{module:"sdk-cache-manager"}});class l{static CACHE_KEY="deway-sdk-cache";static DB_NAME="DewaySdk";static DB_VERSION=1;static STORE_NAME="sdk";async cacheSDK(e,t,n,i){try{const d=(await this.openIndexedDB()).transaction([l.STORE_NAME],"readwrite").objectStore(l.STORE_NAME);await new Promise((k,L)=>{const w=d.put({id:"latest",code:e,version:t,checksum:n,signature:i,timestamp:Date.now()});w.onsuccess=()=>k(w.result),w.onerror=()=>L(w.error)}),f.debug("SDK cached in IndexedDB")}catch{try{const s=JSON.stringify({code:e,version:t,checksum:n,signature:i,timestamp:Date.now()});localStorage.setItem(l.CACHE_KEY,s),f.debug("SDK cached in localStorage")}catch(s){f.warn("Unable to cache SDK",s)}}}async getCachedSDK(){try{const n=(await this.openIndexedDB()).transaction([l.STORE_NAME],"readonly").objectStore(l.STORE_NAME),i=await new Promise((r,s)=>{const d=n.get("latest");d.onsuccess=()=>r(d.result||null),d.onerror=()=>s(d.error)});if(i)return f.debug("Found cached SDK in IndexedDB"),i}catch{f.debug("IndexedDB unavailable, trying localStorage")}try{const e=localStorage.getItem(l.CACHE_KEY);if(e)return f.debug("Found cached SDK in localStorage"),JSON.parse(e)}catch(e){f.warn("Failed to read from localStorage",e)}return null}openIndexedDB(){return new Promise((e,t)=>{const n=indexedDB.open(l.DB_NAME,l.DB_VERSION);n.onerror=()=>t(n.error),n.onsuccess=()=>e(n.result),n.onupgradeneeded=i=>{const r=i.target.result;r.objectStoreNames.contains(l.STORE_NAME)||r.createObjectStore(l.STORE_NAME,{keyPath:"id"})}})}}const z=u({context:{module:"sdk-verifier"}});async function $(o){const t=new TextEncoder().encode(o),n=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(n)).map(r=>r.toString(16).padStart(2,"0")).join("")}function I(o){const e=atob(o),t=new Uint8Array(e.length);for(let n=0;n<e.length;n++)t[n]=e.charCodeAt(n);return t}function q(o){const e=new Uint8Array(o.length/2);for(let t=0;t<o.length;t+=2)e[t/2]=Number.parseInt(o.substr(t,2),16);return e}async function P(o,e,t){try{const n=I(o),i=q(e),r=I(t),s=await crypto.subtle.importKey("raw",n,{name:"Ed25519"},!1,["verify"]);return await crypto.subtle.verify("Ed25519",s,r,i)}catch(n){return z.error("Ed25519 signature verification failed",n),!1}}async function j(o,e,t,n){if(!e||!t)throw new Error("SDK verification failed: Missing security headers");if(await $(o)!==e)throw new Error("SDK verification failed: Checksum mismatch - content tampered");if(!await P(n,e,t))throw new Error("SDK verification failed: Invalid signature - content tampered")}const y=u({context:{module:"sdk-fetcher"}});class V{cleanApiEndpoint(e){return e.trim().replace(/\/+$/,"")}async fetchSDK(e,t,n){try{y.info("Fetching Deway SDK from backend...");const i=this.cleanApiEndpoint(t),r=await fetch(`${i}/sdk-serve/sdk/v0`,{method:"GET",headers:{Accept:"application/javascript","deway-app-key":e,Origin:window?.location?.origin||""}});return r.ok?this.handleSuccessfulFetch(r,n):(y.warn(`Failed to fetch SDK: HTTP ${r.status}: ${r.statusText}`),null)}catch(i){return y.warn("Failed to fetch SDK from server",i),null}}async handleSuccessfulFetch(e,t){const n=e.headers.get("x-sdk-checksum"),i=e.headers.get("x-sdk-version"),r=e.headers.get("x-sdk-signature"),s=await e.text();if(y.info(`Fetched Deway SDK version ${i}`),!i||!s||!n){const d=Object.fromEntries(e.headers.entries());throw y.error("Failed to get required data from sdk fetch",{headers:d}),new Error("Invalid SDK response: missing version, code, or checksum")}return await j(s,n,r,t),{code:s,version:i,checksum:n,signature:r||""}}}const g=u({context:{module:"command-queue"}});class D{static MAX_QUEUE_SIZE=50;commandQueue=[];queueCommand(e,...t){this.commandQueue.length>=D.MAX_QUEUE_SIZE&&(g.warn(`Command queue full (${D.MAX_QUEUE_SIZE} commands). Discarding oldest command.`),this.commandQueue.shift()),this.commandQueue.push({method:e,args:t}),g.debug(`Queued command: ${e} (queue size: ${this.commandQueue.length})`)}replayQueuedCommands(){if(this.commandQueue.length===0)return;g.info(`Replaying ${this.commandQueue.length} queued commands`);const e=[...this.commandQueue];if(this.commandQueue=[],!this.isSDKAvailable()){g.warn("Deway SDK not available for command replay");return}for(const t of e)this.replayCommand(t)}clearQueue(){this.commandQueue=[]}isSDKAvailable(){return typeof window<"u"&&"Deway"in window&&!!window.Deway}replayCommand(e){try{const t=window.Deway,n=t?.[e.method];typeof n=="function"?n.apply(t,e.args):g.warn(`Method ${e.method} not found on Deway SDK`)}catch(t){g.error(`Failed to replay command ${e.method}`,t)}}}const C=u({context:{module:"remote-config-cache"}});class b{static CACHE_KEY="deway-remote-config-cache";async cacheRemoteConfig(e,t){try{const n={config:e,ttl_seconds:t,timestamp:Date.now()};localStorage.setItem(b.CACHE_KEY,JSON.stringify(n)),C.debug("Remote configuration cached in localStorage")}catch(n){C.warn("Failed to cache remote config",n)}}async getCachedRemoteConfig(){try{const e=localStorage.getItem(b.CACHE_KEY);if(!e)return null;const t=JSON.parse(e);return C.debug("Found cached remote configuration"),t}catch(e){return C.warn("Failed to read cached remote config",e),null}}isCacheValid(e,t){const n=Date.now(),i=e+t*1e3;return n<i}}const E=u({context:{module:"remote-config-fetcher"}});class H{cleanApiEndpoint(e){return e.trim().replace(/\/+$/,"")}async fetchRemoteConfig(e,t){try{E.info("Fetching remote configuration from backend...");const n=this.cleanApiEndpoint(t),i=await fetch(`${n}/sdk-remote-config-serve/`,{method:"GET",headers:{Accept:"application/json","deway-app-key":e,Origin:window?.location?.origin||""}});if(i.ok){const r=await i.json();return E.info("Remote configuration fetched successfully"),r}return E.warn(`Failed to fetch remote config: HTTP ${i.status}: ${i.statusText}`),null}catch(n){return E.warn("Failed to fetch remote config from server",n),null}}}const p=u({context:{module:"script-executor"}});class M{async executeSDK(e){return new Promise(t=>{try{if(!this.isDocumentReady()){p.error("Document is not available for script execution"),t(!1);return}const n=document.createElement("script");n.textContent=e,n.type="text/javascript";let i=!1;const r=s=>{i||(i=!0,this.cleanupScript(n),t(s))};n.onerror=()=>{p.error("Script execution failed"),r(!1)},n.onload=()=>r(!0),document.head.appendChild(n),setTimeout(()=>{!i&&this.verifySDKLoaded()?r(!0):i||(p.error("SDK execution timeout - Deway object not found"),r(!1))},100)}catch(n){p.error("Failed to execute SDK script",n),t(!1)}})}isDocumentReady(){return typeof document<"u"&&document.head!=null}verifySDKLoaded(){return typeof window<"u"&&"Deway"in window&&!!window.Deway}cleanupScript(e){try{e.parentNode&&e.parentNode.removeChild(e)}catch(t){p.debug("Failed to cleanup script element",t)}}}const v=u({context:{module:"config-validator"}});class B{validateConfig(e){return e?!e.appKey||e.appKey.trim().length===0?(v.error("Config.appKey is required and must be a non-empty string"),!1):e.apiEndpoint!==void 0&&!this.isValidUrl(e.apiEndpoint)?(v.error("Config.apiEndpoint must be a valid URL"),!1):e.publicKey!==void 0&&e.publicKey.trim().length===0?(v.error("Config.publicKey must be a non-empty string if provided"),!1):!0:(v.error("Config is required"),!1)}isValidUrl(e){try{return new URL(e),!0}catch{return!1}}}const a=u({context:{module:"sdk-loader"}}),K={apiEndpoint:"https://service.deway.app",publicKey:"9d3dBUvqyUQ7egd5j5uORdHSqZ7VFWOu+ud/SWt9WUY="};class W{isLoaded=!1;isLoading=!1;cacheManager;scriptExecutor;commandQueue;sdkFetcher;configValidator;remoteConfigFetcher;remoteConfigCache;sdkConfigStore;constructor(){this.cacheManager=new l,this.scriptExecutor=new M,this.commandQueue=new D,this.sdkFetcher=new V,this.configValidator=new B,this.sdkConfigStore=new O,this.remoteConfigFetcher=new H,this.remoteConfigCache=new b}init(e){this.performInit(e).catch(t=>{a.error("Failed to initialize Deway SDK",t)})}async performInit(e){try{if(!this.canInitialize())return;const t=this.isInitializationPayload(e),n=t?e.localConfig:e;if(!this.configValidator.validateConfig(n)){a.error("Invalid config provided to Deway SDK");return}this.isLoading=!0;const i=n.apiEndpoint||K.apiEndpoint,r=n.publicKey||K.publicKey,[s,d]=await Promise.all([this.fetchOrLoadSDK(n.appKey,i,r),this.fetchRemoteConfigWithCache(n,i)]);if(!s)return;const k=t?e:this.createInitializationPayload(d,n);if(!await this.scriptExecutor.executeSDK(s.code)){a.error("SDK execution failed");return}if(!this.initializeSDK(k))return;this.commandQueue.replayQueuedCommands(),this.isLoaded=!0}finally{this.isLoading=!1}}isInitializationPayload(e){return"localConfig"in e&&"remoteConfig"in e&&"defaults"in e}canInitialize(){return this.isLoaded?(a.warn("Deway SDK already initialized"),!1):this.isLoading?(a.warn("Deway SDK initialization already in progress"),!1):!0}async fetchRemoteConfigWithCache(e,t){this.sdkConfigStore.saveConfig(e);const n=await this.remoteConfigFetcher.fetchRemoteConfig(e.appKey,t);if(n)return await this.remoteConfigCache.cacheRemoteConfig(n.config,n.ttl_seconds),n;a.info("Using cached remote config as fallback");const i=await this.remoteConfigCache.getCachedRemoteConfig();return i?{config:i.config,ttl_seconds:i.ttl_seconds}:(a.warn("No remote config available (fetch failed and no cache)"),null)}createInitializationPayload(e,t){return{localConfig:t,remoteConfig:e?.config??null,defaults:K}}async fetchOrLoadSDK(e,t,n){const i=await this.sdkFetcher.fetchSDK(e,t,n);return i?(await this.cacheManager.cacheSDK(i.code,i.version,i.checksum,i.signature),i):(a.warn("Failed to fetch SDK from server, attempting cache fallback"),this.loadFromCache())}async loadFromCache(){const e=await this.cacheManager.getCachedSDK();return e?(a.info(`Loading cached Deway SDK version ${e.version}`),{code:e.code,version:e.version}):(a.error("SDK unavailable: Network error and no cached version found"),null)}initializeSDK(e){if(!this.isSDKAvailable())return a.error("SDK execution failed: Deway object not found after loading"),!1;try{return window.Deway?.init(e),a.info("Deway SDK initialized successfully with payload"),!0}catch(t){return a.error("Failed to initialize SDK with payload",t),!1}}identify(e){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.identify(e):this.commandQueue.queueCommand("identify",e)}catch(t){a.error("Failed to identify user",t)}}reportEvent(e,t){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.reportEvent(e,t):this.commandQueue.queueCommand("reportEvent",e,t)}catch(n){a.error("Failed to report event",n)}}setUserProfile(e){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.setUserProfile(e):this.commandQueue.queueCommand("setUserProfile",e)}catch(t){a.error("Failed to set user profile",t)}}show(e){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.show(e):this.commandQueue.queueCommand("show",e)}catch(t){a.error("Failed to show bookmark",t)}}hide(){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.hide():this.commandQueue.queueCommand("hide")}catch(e){a.error("Failed to hide bookmark",e)}}openChat(){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.openChat():this.commandQueue.queueCommand("openChat")}catch(e){a.error("Failed to open chat",e)}}resetUserLocally(){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.resetUserLocally():this.commandQueue.queueCommand("resetUserLocally")}catch(e){a.error("Failed to reset user locally",e)}}isVisible(){try{return this.isLoaded&&this.isSDKAvailable()?window.Deway?.isVisible()??!1:!1}catch(e){return a.error("Failed to check bookmark visibility",e),!1}}isInitialized(){try{return this.isLoaded&&this.isSDKAvailable()?window.Deway?.isInitialized()??!1:!1}catch(e){return a.error("Failed to check initialization status",e),!1}}registerSupportCallback(e){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.registerSupportCallback(e):this.commandQueue.queueCommand("registerSupportCallback",e)}catch(t){a.error("Failed to register support callback",t)}}unregisterSupportCallback(){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.unregisterSupportCallback():this.commandQueue.queueCommand("unregisterSupportCallback")}catch(e){a.error("Failed to unregister support callback",e)}}destroy(){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.destroy():this.commandQueue.queueCommand("destroy"),this.commandQueue.clearQueue()}catch(e){a.error("Failed to destroy SDK",e)}}isSDKAvailable(){return typeof window<"u"&&"Deway"in window&&!!window.Deway}}const c=new W,x={init:o=>c.init(o),identify:o=>c.identify(o),reportEvent:(o,e)=>c.reportEvent(o,e),setUserProfile:o=>c.setUserProfile(o),show:o=>c.show(o),hide:()=>c.hide(),openChat:()=>c.openChat(),resetUserLocally:()=>c.resetUserLocally(),registerSupportCallback:o=>c.registerSupportCallback(o),unregisterSupportCallback:()=>c.unregisterSupportCallback(),isVisible:()=>c.isVisible(),isInitialized:()=>c.isInitialized(),destroy:()=>c.destroy()};return typeof window<"u"&&(window.Deway=x),x}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deway-ai/web-sdk",
3
- "version": "0.72.0",
3
+ "version": "0.73.0",
4
4
  "type": "module",
5
5
  "description": "Deway's Web SDK",
6
6
  "main": "dist/loader.umd.js",