@deway-ai/web-sdk 0.42.0 → 0.44.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,17 +1,17 @@
1
- const g = "deway-sdk-config", p = ["Understanding intent", "Reading web page", "Browsing the docs", "Enriching context", "Validating understanding", "Crafting response"];
1
+ const y = "deway-sdk-config", p = ["Understanding intent", "Reading web page", "Browsing the docs", "Enriching context", "Validating understanding", "Crafting response"];
2
2
  class S {
3
3
  saveConfig(e) {
4
4
  if (window?.localStorage)
5
5
  try {
6
6
  const t = JSON.stringify(e);
7
- window.localStorage.setItem(g, t);
7
+ window.localStorage.setItem(y, t);
8
8
  } catch {
9
9
  }
10
10
  }
11
11
  loadConfig() {
12
12
  if (window?.localStorage)
13
13
  try {
14
- const e = window.localStorage.getItem(g);
14
+ const e = window.localStorage.getItem(y);
15
15
  return e ? JSON.parse(e) : null;
16
16
  } catch {
17
17
  return null;
@@ -45,6 +45,21 @@ class S {
45
45
  getPromptSuggestions() {
46
46
  return this.loadConfig()?.promptSuggestions;
47
47
  }
48
+ getBookmarkAppearanceMode() {
49
+ return this.loadConfig()?.bookmarkAppearanceMode ?? "bookmark";
50
+ }
51
+ getTenantTheme() {
52
+ return this.loadConfig()?.tenantTheme ?? null;
53
+ }
54
+ /**
55
+ * Get the theme override for a specific mode
56
+ * @param mode - "light" or "dark"
57
+ * @returns ThemeOverride for the specified mode, or null if not available
58
+ */
59
+ getTenantThemeForMode(e) {
60
+ const t = this.getTenantTheme();
61
+ return t ? e === "dark" ? t.dark : t.light : null;
62
+ }
48
63
  }
49
64
  class s {
50
65
  static CACHE_KEY = "deway-sdk-cache";
@@ -53,9 +68,9 @@ class s {
53
68
  static STORE_NAME = "sdk";
54
69
  async cacheSDK(e, t, i, n) {
55
70
  try {
56
- const c = (await this.openIndexedDB()).transaction([s.STORE_NAME], "readwrite").objectStore(s.STORE_NAME);
57
- await new Promise((f, y) => {
58
- const l = c.put({
71
+ const d = (await this.openIndexedDB()).transaction([s.STORE_NAME], "readwrite").objectStore(s.STORE_NAME);
72
+ await new Promise((h, m) => {
73
+ const l = d.put({
59
74
  id: "latest",
60
75
  code: e,
61
76
  version: t,
@@ -63,27 +78,27 @@ class s {
63
78
  signature: n,
64
79
  timestamp: Date.now()
65
80
  });
66
- l.onsuccess = () => f(l.result), l.onerror = () => y(l.error);
81
+ l.onsuccess = () => h(l.result), l.onerror = () => m(l.error);
67
82
  });
68
83
  } catch {
69
84
  try {
70
- const a = JSON.stringify({
85
+ const o = JSON.stringify({
71
86
  code: e,
72
87
  version: t,
73
88
  checksum: i,
74
89
  signature: n,
75
90
  timestamp: Date.now()
76
91
  });
77
- localStorage.setItem(s.CACHE_KEY, a);
92
+ localStorage.setItem(s.CACHE_KEY, o);
78
93
  } catch {
79
94
  }
80
95
  }
81
96
  }
82
97
  async getCachedSDK() {
83
98
  try {
84
- const i = (await this.openIndexedDB()).transaction([s.STORE_NAME], "readonly").objectStore(s.STORE_NAME), n = await new Promise((o, a) => {
85
- const c = i.get("latest");
86
- c.onsuccess = () => o(c.result || null), c.onerror = () => a(c.error);
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);
87
102
  });
88
103
  if (n)
89
104
  return n;
@@ -101,15 +116,15 @@ class s {
101
116
  return new Promise((e, t) => {
102
117
  const i = indexedDB.open(s.DB_NAME, s.DB_VERSION);
103
118
  i.onerror = () => t(i.error), i.onsuccess = () => e(i.result), i.onupgradeneeded = (n) => {
104
- const o = n.target.result;
105
- o.objectStoreNames.contains(s.STORE_NAME) || o.createObjectStore(s.STORE_NAME, { keyPath: "id" });
119
+ const a = n.target.result;
120
+ a.objectStoreNames.contains(s.STORE_NAME) || a.createObjectStore(s.STORE_NAME, { keyPath: "id" });
106
121
  };
107
122
  });
108
123
  }
109
124
  }
110
125
  async function C(r) {
111
126
  const t = new TextEncoder().encode(r), i = await crypto.subtle.digest("SHA-256", t);
112
- return Array.from(new Uint8Array(i)).map((o) => o.toString(16).padStart(2, "0")).join("");
127
+ return Array.from(new Uint8Array(i)).map((a) => a.toString(16).padStart(2, "0")).join("");
113
128
  }
114
129
  function w(r) {
115
130
  const e = atob(r), t = new Uint8Array(e.length);
@@ -125,8 +140,8 @@ function E(r) {
125
140
  }
126
141
  async function D(r, e, t) {
127
142
  try {
128
- const i = w(r), n = E(e), o = w(t), a = await crypto.subtle.importKey("raw", i, { name: "Ed25519" }, !1, ["verify"]);
129
- return await crypto.subtle.verify("Ed25519", a, o, n);
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);
130
145
  } catch {
131
146
  return !1;
132
147
  }
@@ -139,13 +154,13 @@ async function A(r, e, t, i) {
139
154
  if (!await D(i, e, t))
140
155
  throw new Error("SDK verification failed: Invalid signature - content tampered");
141
156
  }
142
- class v {
157
+ class b {
143
158
  cleanApiEndpoint(e) {
144
159
  return e.trim().replace(/\/+$/, "");
145
160
  }
146
161
  async fetchSDK(e, t, i) {
147
162
  try {
148
- const n = this.cleanApiEndpoint(t), o = await fetch(`${n}/sdk-serve/sdk/v0`, {
163
+ const n = this.cleanApiEndpoint(t), a = await fetch(`${n}/sdk-serve/sdk/v0`, {
149
164
  method: "GET",
150
165
  headers: {
151
166
  Accept: "application/javascript",
@@ -153,23 +168,23 @@ class v {
153
168
  Origin: window?.location?.origin || ""
154
169
  }
155
170
  });
156
- return o.ok ? this.handleSuccessfulFetch(o, i) : null;
171
+ return a.ok ? this.handleSuccessfulFetch(a, i) : null;
157
172
  } catch {
158
173
  return null;
159
174
  }
160
175
  }
161
176
  async handleSuccessfulFetch(e, t) {
162
- 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();
163
- if (!n || !a || !i)
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)
164
179
  throw Object.fromEntries(e.headers.entries()), new Error("Invalid SDK response: missing version, code, or checksum");
165
- return await A(a, i, o, t), { code: a, version: n, checksum: i, signature: o || "" };
180
+ return await A(o, i, a, t), { code: o, version: n, checksum: i, signature: a || "" };
166
181
  }
167
182
  }
168
- class m {
183
+ class g {
169
184
  static MAX_QUEUE_SIZE = 50;
170
185
  commandQueue = [];
171
186
  queueCommand(e, ...t) {
172
- this.commandQueue.length >= m.MAX_QUEUE_SIZE && this.commandQueue.shift(), this.commandQueue.push({ method: e, args: t });
187
+ this.commandQueue.length >= g.MAX_QUEUE_SIZE && this.commandQueue.shift(), this.commandQueue.push({ method: e, args: t });
173
188
  }
174
189
  replayQueuedCommands() {
175
190
  if (this.commandQueue.length === 0)
@@ -240,7 +255,7 @@ class u {
240
255
  return i < n;
241
256
  }
242
257
  }
243
- class b {
258
+ class v {
244
259
  cleanApiEndpoint(e) {
245
260
  return e.trim().replace(/\/+$/, "");
246
261
  }
@@ -279,13 +294,13 @@ class K {
279
294
  const i = document.createElement("script");
280
295
  i.textContent = e, i.type = "text/javascript";
281
296
  let n = !1;
282
- const o = (a) => {
283
- n || (n = !0, this.cleanupScript(i), t(a));
297
+ const a = (o) => {
298
+ n || (n = !0, this.cleanupScript(i), t(o));
284
299
  };
285
300
  i.onerror = () => {
286
- o(!1);
287
- }, i.onload = () => o(!0), document.head.appendChild(i), setTimeout(() => {
288
- !n && this.verifySDKLoaded() ? o(!0) : n || o(!1);
301
+ a(!1);
302
+ }, i.onload = () => a(!0), document.head.appendChild(i), setTimeout(() => {
303
+ !n && this.verifySDKLoaded() ? a(!0) : n || a(!1);
289
304
  }, 100);
290
305
  } catch {
291
306
  t(!1);
@@ -317,13 +332,11 @@ class k {
317
332
  }
318
333
  }
319
334
  }
320
- const h = {
335
+ const f = {
321
336
  apiEndpoint: "https://service.deway.app",
322
- publicKey: "9d3dBUvqyUQ7egd5j5uORdHSqZ7VFWOu+ud/SWt9WUY=",
323
- isDevelopment: !1,
324
- autoShowBookmark: !1
337
+ publicKey: "9d3dBUvqyUQ7egd5j5uORdHSqZ7VFWOu+ud/SWt9WUY="
325
338
  };
326
- class x {
339
+ class I {
327
340
  isLoaded = !1;
328
341
  isLoading = !1;
329
342
  cacheManager;
@@ -335,7 +348,7 @@ class x {
335
348
  remoteConfigCache;
336
349
  sdkConfigStore;
337
350
  constructor() {
338
- this.cacheManager = new s(), this.scriptExecutor = new K(), this.commandQueue = new m(), this.sdkFetcher = new v(), this.configValidator = new k(), this.sdkConfigStore = new S(), this.remoteConfigFetcher = new b(), this.remoteConfigCache = new u();
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();
339
352
  }
340
353
  init(e) {
341
354
  this.performInit(e).catch((t) => {
@@ -349,11 +362,11 @@ class x {
349
362
  if (!this.configValidator.validateConfig(i))
350
363
  return;
351
364
  this.isLoading = !0;
352
- const n = i.apiEndpoint || h.apiEndpoint, o = i.publicKey || h.publicKey, [a, c] = await Promise.all([this.fetchOrLoadSDK(i.appKey, n, o), this.fetchRemoteConfigWithCache(i, n)]);
353
- if (!a)
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)
354
367
  return;
355
- const f = t ? e : this.createInitializationPayload(c, i);
356
- if (!await this.scriptExecutor.executeSDK(a.code) || !this.initializeSDK(f))
368
+ const h = t ? e : this.createInitializationPayload(d, i);
369
+ if (!await this.scriptExecutor.executeSDK(o.code) || !this.initializeSDK(h))
357
370
  return;
358
371
  this.commandQueue.replayQueuedCommands(), this.isLoaded = !0;
359
372
  } finally {
@@ -390,7 +403,7 @@ class x {
390
403
  return {
391
404
  localConfig: t,
392
405
  remoteConfig: e?.config ?? null,
393
- defaults: h
406
+ defaults: f
394
407
  };
395
408
  }
396
409
  async fetchOrLoadSDK(e, t, i) {
@@ -447,6 +460,13 @@ class x {
447
460
  return !1;
448
461
  }
449
462
  }
463
+ isInitialized() {
464
+ try {
465
+ return this.isLoaded && this.isSDKAvailable() ? window.Deway?.isInitialized() ?? !1 : !1;
466
+ } catch {
467
+ return !1;
468
+ }
469
+ }
450
470
  destroy() {
451
471
  try {
452
472
  this.isLoaded && this.isSDKAvailable() ? window.Deway?.destroy() : this.commandQueue.queueCommand("destroy"), this.commandQueue.clearQueue();
@@ -457,17 +477,18 @@ class x {
457
477
  return typeof window < "u" && "Deway" in window && !!window.Deway;
458
478
  }
459
479
  }
460
- const d = new x(), I = {
461
- init: (r) => d.init(r),
462
- identify: (r) => d.identify(r),
463
- reportEvent: (r, e) => d.reportEvent(r, e),
464
- setUserProfile: (r) => d.setUserProfile(r),
465
- show: (r) => d.show(r),
466
- hide: () => d.hide(),
467
- isVisible: () => d.isVisible(),
468
- destroy: () => d.destroy()
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),
486
+ hide: () => c.hide(),
487
+ isVisible: () => c.isVisible(),
488
+ isInitialized: () => c.isInitialized(),
489
+ destroy: () => c.destroy()
469
490
  };
470
- typeof window < "u" && (window.Deway = I);
491
+ typeof window < "u" && (window.Deway = T);
471
492
  export {
472
- I as default
493
+ T as default
473
494
  };
@@ -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}}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((g,S)=>{const f=d.put({id:"latest",code:e,version:t,checksum:i,signature:n,timestamp:Date.now()});f.onsuccess=()=>g(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 v(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 b{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 v(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 x{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 y={apiEndpoint:"https://service.deway.app",publicKey:"9d3dBUvqyUQ7egd5j5uORdHSqZ7VFWOu+ud/SWt9WUY=",isDevelopment:!1,autoShowBookmark:!1};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 b,this.configValidator=new x,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||y.apiEndpoint,o=i.publicKey||y.publicKey,[a,d]=await Promise.all([this.fetchOrLoadSDK(i.appKey,n,o),this.fetchRemoteConfigWithCache(i,n)]);if(!a)return;const g=t?e:this.createInitializationPayload(d,i);if(!await this.scriptExecutor.executeSDK(a.code)||!this.initializeSDK(g))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:y}}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}}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(),destroy:()=>c.destroy()};return typeof window<"u"&&(window.Deway=p),p}));
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}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deway-ai/web-sdk",
3
- "version": "0.42.0",
3
+ "version": "0.44.0",
4
4
  "type": "module",
5
5
  "description": "Deway's Web SDK",
6
6
  "main": "dist/loader.umd.js",