@deway-ai/web-sdk 0.44.0 → 0.46.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
@@ -30,11 +30,19 @@ class S {
30
30
  getThinkingMessages() {
31
31
  return this.loadConfig()?.thinkingMessages ?? p;
32
32
  }
33
- getTalkToHumanBtnTxt() {
34
- return this.loadConfig()?.talkToHumanBtnTxt ?? "talk to Support";
33
+ /**
34
+ * Get the support handoff configuration
35
+ * @returns SupportHandoff config or null if not configured
36
+ */
37
+ getSupportHandoff() {
38
+ return this.loadConfig()?.supportHandoff ?? null;
35
39
  }
36
- getHumanHandoffUrl() {
37
- return this.loadConfig()?.humanHandoffUrl;
40
+ /**
41
+ * Get the support handoff button text
42
+ * @returns Custom button text or default "talk to Support"
43
+ */
44
+ getSupportHandoffButtonText() {
45
+ return this.getSupportHandoff()?.button_text ?? "talk to Support";
38
46
  }
39
47
  getFeatureFlags() {
40
48
  return this.loadConfig()?.featureFlags ?? {};
@@ -45,6 +53,12 @@ class S {
45
53
  getPromptSuggestions() {
46
54
  return this.loadConfig()?.promptSuggestions;
47
55
  }
56
+ getWelcomeTitle() {
57
+ return this.loadConfig()?.welcomeTitle ?? "How can I help you today?";
58
+ }
59
+ getWelcomeSubtitle() {
60
+ return this.loadConfig()?.welcomeSubtitle ?? "I'm ready to help you navigate, learn, and get things done.";
61
+ }
48
62
  getBookmarkAppearanceMode() {
49
63
  return this.loadConfig()?.bookmarkAppearanceMode ?? "bookmark";
50
64
  }
@@ -60,48 +74,57 @@ class S {
60
74
  const t = this.getTenantTheme();
61
75
  return t ? e === "dark" ? t.dark : t.light : null;
62
76
  }
77
+ getCustomIcons() {
78
+ return this.loadConfig()?.customIcons ?? null;
79
+ }
80
+ getBookmarkIconInlineSvg() {
81
+ return this.getCustomIcons()?.bookmark_icon_inline_svg ?? void 0;
82
+ }
83
+ getEmptyChatStateIconInlineSvg() {
84
+ return this.getCustomIcons()?.empty_chat_state_icon_inline_svg ?? void 0;
85
+ }
63
86
  }
64
87
  class s {
65
88
  static CACHE_KEY = "deway-sdk-cache";
66
89
  static DB_NAME = "DewaySdk";
67
90
  static DB_VERSION = 1;
68
91
  static STORE_NAME = "sdk";
69
- async cacheSDK(e, t, i, n) {
92
+ async cacheSDK(e, t, n, i) {
70
93
  try {
71
94
  const d = (await this.openIndexedDB()).transaction([s.STORE_NAME], "readwrite").objectStore(s.STORE_NAME);
72
- await new Promise((h, m) => {
95
+ await new Promise((f, m) => {
73
96
  const l = d.put({
74
97
  id: "latest",
75
98
  code: e,
76
99
  version: t,
77
- checksum: i,
78
- signature: n,
100
+ checksum: n,
101
+ signature: i,
79
102
  timestamp: Date.now()
80
103
  });
81
- l.onsuccess = () => h(l.result), l.onerror = () => m(l.error);
104
+ l.onsuccess = () => f(l.result), l.onerror = () => m(l.error);
82
105
  });
83
106
  } catch {
84
107
  try {
85
- const o = JSON.stringify({
108
+ const a = JSON.stringify({
86
109
  code: e,
87
110
  version: t,
88
- checksum: i,
89
- signature: n,
111
+ checksum: n,
112
+ signature: i,
90
113
  timestamp: Date.now()
91
114
  });
92
- localStorage.setItem(s.CACHE_KEY, o);
115
+ localStorage.setItem(s.CACHE_KEY, a);
93
116
  } catch {
94
117
  }
95
118
  }
96
119
  }
97
120
  async getCachedSDK() {
98
121
  try {
99
- const i = (await this.openIndexedDB()).transaction([s.STORE_NAME], "readonly").objectStore(s.STORE_NAME), n = await new Promise((a, o) => {
100
- const d = i.get("latest");
101
- d.onsuccess = () => a(d.result || null), d.onerror = () => o(d.error);
122
+ const n = (await this.openIndexedDB()).transaction([s.STORE_NAME], "readonly").objectStore(s.STORE_NAME), i = await new Promise((r, a) => {
123
+ const d = n.get("latest");
124
+ d.onsuccess = () => r(d.result || null), d.onerror = () => a(d.error);
102
125
  });
103
- if (n)
104
- return n;
126
+ if (i)
127
+ return i;
105
128
  } catch {
106
129
  }
107
130
  try {
@@ -114,53 +137,53 @@ class s {
114
137
  }
115
138
  openIndexedDB() {
116
139
  return new Promise((e, t) => {
117
- const i = indexedDB.open(s.DB_NAME, s.DB_VERSION);
118
- i.onerror = () => t(i.error), i.onsuccess = () => e(i.result), i.onupgradeneeded = (n) => {
119
- const a = n.target.result;
120
- a.objectStoreNames.contains(s.STORE_NAME) || a.createObjectStore(s.STORE_NAME, { keyPath: "id" });
140
+ const n = indexedDB.open(s.DB_NAME, s.DB_VERSION);
141
+ n.onerror = () => t(n.error), n.onsuccess = () => e(n.result), n.onupgradeneeded = (i) => {
142
+ const r = i.target.result;
143
+ r.objectStoreNames.contains(s.STORE_NAME) || r.createObjectStore(s.STORE_NAME, { keyPath: "id" });
121
144
  };
122
145
  });
123
146
  }
124
147
  }
125
- async function C(r) {
126
- const t = new TextEncoder().encode(r), i = await crypto.subtle.digest("SHA-256", t);
127
- return Array.from(new Uint8Array(i)).map((a) => a.toString(16).padStart(2, "0")).join("");
148
+ async function C(o) {
149
+ const t = new TextEncoder().encode(o), n = await crypto.subtle.digest("SHA-256", t);
150
+ return Array.from(new Uint8Array(n)).map((r) => r.toString(16).padStart(2, "0")).join("");
128
151
  }
129
- function w(r) {
130
- const e = atob(r), t = new Uint8Array(e.length);
131
- for (let i = 0; i < e.length; i++)
132
- t[i] = e.charCodeAt(i);
152
+ function w(o) {
153
+ const e = atob(o), t = new Uint8Array(e.length);
154
+ for (let n = 0; n < e.length; n++)
155
+ t[n] = e.charCodeAt(n);
133
156
  return t;
134
157
  }
135
- function E(r) {
136
- const e = new Uint8Array(r.length / 2);
137
- for (let t = 0; t < r.length; t += 2)
138
- e[t / 2] = Number.parseInt(r.substr(t, 2), 16);
158
+ function E(o) {
159
+ const e = new Uint8Array(o.length / 2);
160
+ for (let t = 0; t < o.length; t += 2)
161
+ e[t / 2] = Number.parseInt(o.substr(t, 2), 16);
139
162
  return e;
140
163
  }
141
- async function D(r, e, t) {
164
+ async function D(o, e, t) {
142
165
  try {
143
- const i = w(r), n = E(e), a = w(t), o = await crypto.subtle.importKey("raw", i, { name: "Ed25519" }, !1, ["verify"]);
144
- return await crypto.subtle.verify("Ed25519", o, a, n);
166
+ const n = w(o), i = E(e), r = w(t), a = await crypto.subtle.importKey("raw", n, { name: "Ed25519" }, !1, ["verify"]);
167
+ return await crypto.subtle.verify("Ed25519", a, r, i);
145
168
  } catch {
146
169
  return !1;
147
170
  }
148
171
  }
149
- async function A(r, e, t, i) {
172
+ async function v(o, e, t, n) {
150
173
  if (!e || !t)
151
174
  throw new Error("SDK verification failed: Missing security headers");
152
- if (await C(r) !== e)
175
+ if (await C(o) !== e)
153
176
  throw new Error("SDK verification failed: Checksum mismatch - content tampered");
154
- if (!await D(i, e, t))
177
+ if (!await D(n, e, t))
155
178
  throw new Error("SDK verification failed: Invalid signature - content tampered");
156
179
  }
157
- class b {
180
+ class A {
158
181
  cleanApiEndpoint(e) {
159
182
  return e.trim().replace(/\/+$/, "");
160
183
  }
161
- async fetchSDK(e, t, i) {
184
+ async fetchSDK(e, t, n) {
162
185
  try {
163
- const n = this.cleanApiEndpoint(t), a = await fetch(`${n}/sdk-serve/sdk/v0`, {
186
+ const i = this.cleanApiEndpoint(t), r = await fetch(`${i}/sdk-serve/sdk/v0`, {
164
187
  method: "GET",
165
188
  headers: {
166
189
  Accept: "application/javascript",
@@ -168,16 +191,16 @@ class b {
168
191
  Origin: window?.location?.origin || ""
169
192
  }
170
193
  });
171
- return a.ok ? this.handleSuccessfulFetch(a, i) : null;
194
+ return r.ok ? this.handleSuccessfulFetch(r, n) : null;
172
195
  } catch {
173
196
  return null;
174
197
  }
175
198
  }
176
199
  async handleSuccessfulFetch(e, t) {
177
- const i = e.headers.get("x-sdk-checksum"), n = e.headers.get("x-sdk-version"), a = e.headers.get("x-sdk-signature"), o = await e.text();
178
- if (!n || !o || !i)
200
+ 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();
201
+ if (!i || !a || !n)
179
202
  throw Object.fromEntries(e.headers.entries()), new Error("Invalid SDK response: missing version, code, or checksum");
180
- return await A(o, i, a, t), { code: o, version: n, checksum: i, signature: a || "" };
203
+ return await v(a, n, r, t), { code: a, version: i, checksum: n, signature: r || "" };
181
204
  }
182
205
  }
183
206
  class g {
@@ -202,8 +225,8 @@ class g {
202
225
  }
203
226
  replayCommand(e) {
204
227
  try {
205
- const t = window.Deway, i = t?.[e.method];
206
- typeof i == "function" && i.apply(t, e.args);
228
+ const t = window.Deway, n = t?.[e.method];
229
+ typeof n == "function" && n.apply(t, e.args);
207
230
  } catch {
208
231
  }
209
232
  }
@@ -219,12 +242,12 @@ class u {
219
242
  */
220
243
  async cacheRemoteConfig(e, t) {
221
244
  try {
222
- const i = {
245
+ const n = {
223
246
  config: e,
224
247
  ttl_seconds: t,
225
248
  timestamp: Date.now()
226
249
  };
227
- localStorage.setItem(u.CACHE_KEY, JSON.stringify(i));
250
+ localStorage.setItem(u.CACHE_KEY, JSON.stringify(n));
228
251
  } catch {
229
252
  }
230
253
  }
@@ -251,11 +274,11 @@ class u {
251
274
  * @returns true if cache is still valid
252
275
  */
253
276
  isCacheValid(e, t) {
254
- const i = Date.now(), n = e + t * 1e3;
255
- return i < n;
277
+ const n = Date.now(), i = e + t * 1e3;
278
+ return n < i;
256
279
  }
257
280
  }
258
- class v {
281
+ class b {
259
282
  cleanApiEndpoint(e) {
260
283
  return e.trim().replace(/\/+$/, "");
261
284
  }
@@ -269,7 +292,7 @@ class v {
269
292
  */
270
293
  async fetchRemoteConfig(e, t) {
271
294
  try {
272
- const i = this.cleanApiEndpoint(t), n = await fetch(`${i}/sdk-remote-config-serve/`, {
295
+ const n = this.cleanApiEndpoint(t), i = await fetch(`${n}/sdk-remote-config-serve/`, {
273
296
  method: "GET",
274
297
  headers: {
275
298
  Accept: "application/json",
@@ -277,13 +300,13 @@ class v {
277
300
  Origin: window?.location?.origin || ""
278
301
  }
279
302
  });
280
- return n.ok ? await n.json() : null;
303
+ return i.ok ? await i.json() : null;
281
304
  } catch {
282
305
  return null;
283
306
  }
284
307
  }
285
308
  }
286
- class K {
309
+ class I {
287
310
  async executeSDK(e) {
288
311
  return new Promise((t) => {
289
312
  try {
@@ -291,16 +314,16 @@ class K {
291
314
  t(!1);
292
315
  return;
293
316
  }
294
- const i = document.createElement("script");
295
- i.textContent = e, i.type = "text/javascript";
296
- let n = !1;
297
- const a = (o) => {
298
- n || (n = !0, this.cleanupScript(i), t(o));
317
+ const n = document.createElement("script");
318
+ n.textContent = e, n.type = "text/javascript";
319
+ let i = !1;
320
+ const r = (a) => {
321
+ i || (i = !0, this.cleanupScript(n), t(a));
299
322
  };
300
- i.onerror = () => {
301
- a(!1);
302
- }, i.onload = () => a(!0), document.head.appendChild(i), setTimeout(() => {
303
- !n && this.verifySDKLoaded() ? a(!0) : n || a(!1);
323
+ n.onerror = () => {
324
+ r(!1);
325
+ }, n.onload = () => r(!0), document.head.appendChild(n), setTimeout(() => {
326
+ !i && this.verifySDKLoaded() ? r(!0) : i || r(!1);
304
327
  }, 100);
305
328
  } catch {
306
329
  t(!1);
@@ -320,7 +343,7 @@ class K {
320
343
  }
321
344
  }
322
345
  }
323
- class k {
346
+ class K {
324
347
  validateConfig(e) {
325
348
  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);
326
349
  }
@@ -332,11 +355,11 @@ class k {
332
355
  }
333
356
  }
334
357
  }
335
- const f = {
358
+ const h = {
336
359
  apiEndpoint: "https://service.deway.app",
337
360
  publicKey: "9d3dBUvqyUQ7egd5j5uORdHSqZ7VFWOu+ud/SWt9WUY="
338
361
  };
339
- class I {
362
+ class k {
340
363
  isLoaded = !1;
341
364
  isLoading = !1;
342
365
  cacheManager;
@@ -348,7 +371,7 @@ class I {
348
371
  remoteConfigCache;
349
372
  sdkConfigStore;
350
373
  constructor() {
351
- this.cacheManager = new s(), this.scriptExecutor = new K(), this.commandQueue = new g(), this.sdkFetcher = new b(), this.configValidator = new k(), this.sdkConfigStore = new S(), this.remoteConfigFetcher = new v(), this.remoteConfigCache = new u();
374
+ this.cacheManager = new s(), this.scriptExecutor = new I(), this.commandQueue = new g(), this.sdkFetcher = new A(), this.configValidator = new K(), this.sdkConfigStore = new S(), this.remoteConfigFetcher = new b(), this.remoteConfigCache = new u();
352
375
  }
353
376
  init(e) {
354
377
  this.performInit(e).catch((t) => {
@@ -358,15 +381,15 @@ class I {
358
381
  try {
359
382
  if (!this.canInitialize())
360
383
  return;
361
- const t = this.isInitializationPayload(e), i = t ? e.localConfig : e;
362
- if (!this.configValidator.validateConfig(i))
384
+ const t = this.isInitializationPayload(e), n = t ? e.localConfig : e;
385
+ if (!this.configValidator.validateConfig(n))
363
386
  return;
364
387
  this.isLoading = !0;
365
- const n = i.apiEndpoint || f.apiEndpoint, a = i.publicKey || f.publicKey, [o, d] = await Promise.all([this.fetchOrLoadSDK(i.appKey, n, a), this.fetchRemoteConfigWithCache(i, n)]);
366
- if (!o)
388
+ const i = n.apiEndpoint || h.apiEndpoint, r = n.publicKey || h.publicKey, [a, d] = await Promise.all([this.fetchOrLoadSDK(n.appKey, i, r), this.fetchRemoteConfigWithCache(n, i)]);
389
+ if (!a)
367
390
  return;
368
- const h = t ? e : this.createInitializationPayload(d, i);
369
- if (!await this.scriptExecutor.executeSDK(o.code) || !this.initializeSDK(h))
391
+ const f = t ? e : this.createInitializationPayload(d, n);
392
+ if (!await this.scriptExecutor.executeSDK(a.code) || !this.initializeSDK(f))
370
393
  return;
371
394
  this.commandQueue.replayQueuedCommands(), this.isLoaded = !0;
372
395
  } finally {
@@ -385,13 +408,13 @@ class I {
385
408
  */
386
409
  async fetchRemoteConfigWithCache(e, t) {
387
410
  this.sdkConfigStore.saveConfig(e);
388
- const i = await this.remoteConfigFetcher.fetchRemoteConfig(e.appKey, t);
389
- if (i)
390
- return await this.remoteConfigCache.cacheRemoteConfig(i.config, i.ttl_seconds), i;
391
- const n = await this.remoteConfigCache.getCachedRemoteConfig();
392
- return n ? {
393
- config: n.config,
394
- ttl_seconds: n.ttl_seconds
411
+ const n = await this.remoteConfigFetcher.fetchRemoteConfig(e.appKey, t);
412
+ if (n)
413
+ return await this.remoteConfigCache.cacheRemoteConfig(n.config, n.ttl_seconds), n;
414
+ const i = await this.remoteConfigCache.getCachedRemoteConfig();
415
+ return i ? {
416
+ config: i.config,
417
+ ttl_seconds: i.ttl_seconds
395
418
  } : null;
396
419
  }
397
420
  /**
@@ -403,12 +426,12 @@ class I {
403
426
  return {
404
427
  localConfig: t,
405
428
  remoteConfig: e?.config ?? null,
406
- defaults: f
429
+ defaults: h
407
430
  };
408
431
  }
409
- async fetchOrLoadSDK(e, t, i) {
410
- const n = await this.sdkFetcher.fetchSDK(e, t, i);
411
- return n ? (await this.cacheManager.cacheSDK(n.code, n.version, n.checksum, n.signature), n) : this.loadFromCache();
432
+ async fetchOrLoadSDK(e, t, n) {
433
+ const i = await this.sdkFetcher.fetchSDK(e, t, n);
434
+ return i ? (await this.cacheManager.cacheSDK(i.code, i.version, i.checksum, i.signature), i) : this.loadFromCache();
412
435
  }
413
436
  async loadFromCache() {
414
437
  const e = await this.cacheManager.getCachedSDK();
@@ -477,18 +500,18 @@ class I {
477
500
  return typeof window < "u" && "Deway" in window && !!window.Deway;
478
501
  }
479
502
  }
480
- const c = new I(), T = {
481
- init: (r) => c.init(r),
482
- identify: (r) => c.identify(r),
483
- reportEvent: (r, e) => c.reportEvent(r, e),
484
- setUserProfile: (r) => c.setUserProfile(r),
485
- show: (r) => c.show(r),
503
+ const c = new k(), x = {
504
+ init: (o) => c.init(o),
505
+ identify: (o) => c.identify(o),
506
+ reportEvent: (o, e) => c.reportEvent(o, e),
507
+ setUserProfile: (o) => c.setUserProfile(o),
508
+ show: (o) => c.show(o),
486
509
  hide: () => c.hide(),
487
510
  isVisible: () => c.isVisible(),
488
511
  isInitialized: () => c.isInitialized(),
489
512
  destroy: () => c.destroy()
490
513
  };
491
- typeof window < "u" && (window.Deway = T);
514
+ typeof window < "u" && (window.Deway = x);
492
515
  export {
493
- T as default
516
+ x as default
494
517
  };
@@ -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}getTalkToHumanBtnTxt(){return this.loadConfig()?.talkToHumanBtnTxt??"talk to Support"}getHumanHandoffUrl(){return this.loadConfig()?.humanHandoffUrl}getFeatureFlags(){return this.loadConfig()?.featureFlags??{}}getFeatureFlag(e){return this.getFeatureFlags()[e]??!1}getPromptSuggestions(){return this.loadConfig()?.promptSuggestions}getBookmarkAppearanceMode(){return this.loadConfig()?.bookmarkAppearanceMode??"bookmark"}getTenantTheme(){return this.loadConfig()?.tenantTheme??null}getTenantThemeForMode(e){const t=this.getTenantTheme();return t?e==="dark"?t.dark:t.light:null}}class s{static CACHE_KEY="deway-sdk-cache";static DB_NAME="DewaySdk";static DB_VERSION=1;static STORE_NAME="sdk";async cacheSDK(e,t,i,n){try{const d=(await this.openIndexedDB()).transaction([s.STORE_NAME],"readwrite").objectStore(s.STORE_NAME);await new Promise((y,S)=>{const f=d.put({id:"latest",code:e,version:t,checksum:i,signature:n,timestamp:Date.now()});f.onsuccess=()=>y(f.result),f.onerror=()=>S(f.error)})}catch{try{const a=JSON.stringify({code:e,version:t,checksum:i,signature:n,timestamp:Date.now()});localStorage.setItem(s.CACHE_KEY,a)}catch{}}}async getCachedSDK(){try{const i=(await this.openIndexedDB()).transaction([s.STORE_NAME],"readonly").objectStore(s.STORE_NAME),n=await new Promise((o,a)=>{const d=i.get("latest");d.onsuccess=()=>o(d.result||null),d.onerror=()=>a(d.error)});if(n)return n}catch{}try{const e=localStorage.getItem(s.CACHE_KEY);if(e)return JSON.parse(e)}catch{}return null}openIndexedDB(){return new Promise((e,t)=>{const i=indexedDB.open(s.DB_NAME,s.DB_VERSION);i.onerror=()=>t(i.error),i.onsuccess=()=>e(i.result),i.onupgradeneeded=n=>{const o=n.target.result;o.objectStoreNames.contains(s.STORE_NAME)||o.createObjectStore(s.STORE_NAME,{keyPath:"id"})}})}}async function E(r){const t=new TextEncoder().encode(r),i=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(i)).map(o=>o.toString(16).padStart(2,"0")).join("")}function w(r){const e=atob(r),t=new Uint8Array(e.length);for(let i=0;i<e.length;i++)t[i]=e.charCodeAt(i);return t}function D(r){const e=new Uint8Array(r.length/2);for(let t=0;t<r.length;t+=2)e[t/2]=Number.parseInt(r.substr(t,2),16);return e}async function A(r,e,t){try{const i=w(r),n=D(e),o=w(t),a=await crypto.subtle.importKey("raw",i,{name:"Ed25519"},!1,["verify"]);return await crypto.subtle.verify("Ed25519",a,o,n)}catch{return!1}}async function b(r,e,t,i){if(!e||!t)throw new Error("SDK verification failed: Missing security headers");if(await E(r)!==e)throw new Error("SDK verification failed: Checksum mismatch - content tampered");if(!await A(i,e,t))throw new Error("SDK verification failed: Invalid signature - content tampered")}class v{cleanApiEndpoint(e){return e.trim().replace(/\/+$/,"")}async fetchSDK(e,t,i){try{const n=this.cleanApiEndpoint(t),o=await fetch(`${n}/sdk-serve/sdk/v0`,{method:"GET",headers:{Accept:"application/javascript","deway-app-key":e,Origin:window?.location?.origin||""}});return o.ok?this.handleSuccessfulFetch(o,i):null}catch{return null}}async handleSuccessfulFetch(e,t){const i=e.headers.get("x-sdk-checksum"),n=e.headers.get("x-sdk-version"),o=e.headers.get("x-sdk-signature"),a=await e.text();if(!n||!a||!i)throw Object.fromEntries(e.headers.entries()),new Error("Invalid SDK response: missing version, code, or checksum");return await b(a,i,o,t),{code:a,version:n,checksum:i,signature:o||""}}}class m{static MAX_QUEUE_SIZE=50;commandQueue=[];queueCommand(e,...t){this.commandQueue.length>=m.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,i=t?.[e.method];typeof i=="function"&&i.apply(t,e.args)}catch{}}}class h{static CACHE_KEY="deway-remote-config-cache";async cacheRemoteConfig(e,t){try{const i={config:e,ttl_seconds:t,timestamp:Date.now()};localStorage.setItem(h.CACHE_KEY,JSON.stringify(i))}catch{}}async getCachedRemoteConfig(){try{const e=localStorage.getItem(h.CACHE_KEY);return e?JSON.parse(e):null}catch{return null}}isCacheValid(e,t){const i=Date.now(),n=e+t*1e3;return i<n}}class K{cleanApiEndpoint(e){return e.trim().replace(/\/+$/,"")}async fetchRemoteConfig(e,t){try{const i=this.cleanApiEndpoint(t),n=await fetch(`${i}/sdk-remote-config-serve/`,{method:"GET",headers:{Accept:"application/json","deway-app-key":e,Origin:window?.location?.origin||""}});return n.ok?await n.json():null}catch{return null}}}class k{async executeSDK(e){return new Promise(t=>{try{if(!this.isDocumentReady()){t(!1);return}const i=document.createElement("script");i.textContent=e,i.type="text/javascript";let n=!1;const o=a=>{n||(n=!0,this.cleanupScript(i),t(a))};i.onerror=()=>{o(!1)},i.onload=()=>o(!0),document.head.appendChild(i),setTimeout(()=>{!n&&this.verifySDKLoaded()?o(!0):n||o(!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 T{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 g={apiEndpoint:"https://service.deway.app",publicKey:"9d3dBUvqyUQ7egd5j5uORdHSqZ7VFWOu+ud/SWt9WUY="};class I{isLoaded=!1;isLoading=!1;cacheManager;scriptExecutor;commandQueue;sdkFetcher;configValidator;remoteConfigFetcher;remoteConfigCache;sdkConfigStore;constructor(){this.cacheManager=new s,this.scriptExecutor=new k,this.commandQueue=new m,this.sdkFetcher=new v,this.configValidator=new T,this.sdkConfigStore=new C,this.remoteConfigFetcher=new K,this.remoteConfigCache=new h}init(e){this.performInit(e).catch(t=>{})}async performInit(e){try{if(!this.canInitialize())return;const t=this.isInitializationPayload(e),i=t?e.localConfig:e;if(!this.configValidator.validateConfig(i))return;this.isLoading=!0;const n=i.apiEndpoint||g.apiEndpoint,o=i.publicKey||g.publicKey,[a,d]=await Promise.all([this.fetchOrLoadSDK(i.appKey,n,o),this.fetchRemoteConfigWithCache(i,n)]);if(!a)return;const y=t?e:this.createInitializationPayload(d,i);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 i=await this.remoteConfigFetcher.fetchRemoteConfig(e.appKey,t);if(i)return await this.remoteConfigCache.cacheRemoteConfig(i.config,i.ttl_seconds),i;const n=await this.remoteConfigCache.getCachedRemoteConfig();return n?{config:n.config,ttl_seconds:n.ttl_seconds}:null}createInitializationPayload(e,t){return{localConfig:t,remoteConfig:e?.config??null,defaults:g}}async fetchOrLoadSDK(e,t,i){const n=await this.sdkFetcher.fetchSDK(e,t,i);return n?(await this.cacheManager.cacheSDK(n.code,n.version,n.checksum,n.signature),n):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{}}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}}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 c=new I,p={init:r=>c.init(r),identify:r=>c.identify(r),reportEvent:(r,e)=>c.reportEvent(r,e),setUserProfile:r=>c.setUserProfile(r),show:r=>c.show(r),hide:()=>c.hide(),isVisible:()=>c.isVisible(),isInitialized:()=>c.isInitialized(),destroy:()=>c.destroy()};return typeof window<"u"&&(window.Deway=p),p}));
1
+ (function(u,l){typeof exports=="object"&&typeof module<"u"?module.exports=l():typeof define=="function"&&define.amd?define(l):(u=typeof globalThis<"u"?globalThis:u||self,u.Deway=l())})(this,(function(){"use strict";const u="deway-sdk-config",l=["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(u,t)}catch{}}loadConfig(){if(window?.localStorage)try{const e=window.localStorage.getItem(u);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??l}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."}getBookmarkAppearanceMode(){return this.loadConfig()?.bookmarkAppearanceMode??"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}getBookmarkIconInlineSvg(){return this.getCustomIcons()?.bookmark_icon_inline_svg??void 0}getEmptyChatStateIconInlineSvg(){return this.getCustomIcons()?.empty_chat_state_icon_inline_svg??void 0}}class s{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([s.STORE_NAME],"readwrite").objectStore(s.STORE_NAME);await new Promise((y,S)=>{const f=d.put({id:"latest",code:e,version:t,checksum:n,signature:i,timestamp:Date.now()});f.onsuccess=()=>y(f.result),f.onerror=()=>S(f.error)})}catch{try{const a=JSON.stringify({code:e,version:t,checksum:n,signature:i,timestamp:Date.now()});localStorage.setItem(s.CACHE_KEY,a)}catch{}}}async getCachedSDK(){try{const n=(await this.openIndexedDB()).transaction([s.STORE_NAME],"readonly").objectStore(s.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(s.CACHE_KEY);if(e)return JSON.parse(e)}catch{}return null}openIndexedDB(){return new Promise((e,t)=>{const n=indexedDB.open(s.DB_NAME,s.DB_VERSION);n.onerror=()=>t(n.error),n.onsuccess=()=>e(n.result),n.onupgradeneeded=i=>{const r=i.target.result;r.objectStoreNames.contains(s.STORE_NAME)||r.createObjectStore(s.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 w(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 v(o,e,t){try{const n=w(o),i=D(e),r=w(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 A(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 v(n,e,t))throw new Error("SDK verification failed: Invalid signature - content tampered")}class b{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 A(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 h{static CACHE_KEY="deway-remote-config-cache";async cacheRemoteConfig(e,t){try{const n={config:e,ttl_seconds:t,timestamp:Date.now()};localStorage.setItem(h.CACHE_KEY,JSON.stringify(n))}catch{}}async getCachedRemoteConfig(){try{const e=localStorage.getItem(h.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 x{isLoaded=!1;isLoading=!1;cacheManager;scriptExecutor;commandQueue;sdkFetcher;configValidator;remoteConfigFetcher;remoteConfigCache;sdkConfigStore;constructor(){this.cacheManager=new s,this.scriptExecutor=new K,this.commandQueue=new g,this.sdkFetcher=new b,this.configValidator=new k,this.sdkConfigStore=new C,this.remoteConfigFetcher=new I,this.remoteConfigCache=new h}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{}}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}}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 c=new x,p={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(),isVisible:()=>c.isVisible(),isInitialized:()=>c.isInitialized(),destroy:()=>c.destroy()};return typeof window<"u"&&(window.Deway=p),p}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deway-ai/web-sdk",
3
- "version": "0.44.0",
3
+ "version": "0.46.0",
4
4
  "type": "module",
5
5
  "description": "Deway's Web SDK",
6
6
  "main": "dist/loader.umd.js",