@deway-ai/web-sdk 0.41.0 → 0.43.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/README.md CHANGED
@@ -87,7 +87,7 @@ Deway.init({
87
87
  apiEndpoint: string | undefined, // Optional: Custom API endpoint
88
88
  wsEndpoint: string | undefined, // Optional: Custom WebSocket endpoint
89
89
  isDevelopment: boolean | undefined, // Optional: Enable dev mode logging (default: false)
90
- autoShowBubble: boolean | undefined, // Optional: Auto-show bubble (default: true)
90
+ autoShowBookmark: boolean | undefined, // Optional: Auto-show bubble (default: true)
91
91
  bubbleConfig: BubbleConfig | undefined, // Optional: Bubble appearance customization
92
92
  });
93
93
  ```
@@ -113,7 +113,7 @@ enum BubblePosition {
113
113
  Deway.init({
114
114
  appKey: 'your-app-key',
115
115
  isDevelopment: true,
116
- autoShowBubble: true,
116
+ autoShowBookmark: true,
117
117
  bubbleConfig: {
118
118
  position: 'bottom-left'
119
119
  }
@@ -177,17 +177,17 @@ Deway.setUserProfile({
177
177
  - Profile is upserted (created if new, replaced if exists)
178
178
  - Profile data completely replaces existing profile on each call
179
179
 
180
- ### `Deway.showBubble(config?)`
180
+ ### `Deway.showBookmark(config?)`
181
181
 
182
- Show the AI chat bubble. Optional configuration for appearance customization.
182
+ Show the AI chat bookmark. Optional configuration for appearance customization.
183
183
 
184
- ### `Deway.hideBubble()`
184
+ ### `Deway.hideBookmark()`
185
185
 
186
- Hide the AI chat bubble.
186
+ Hide the AI chat bookmark.
187
187
 
188
- ### `Deway.isBubbleVisible()`
188
+ ### `Deway.isBookmarkVisible()`
189
189
 
190
- Check if the bubble is currently visible.
190
+ Check if the bookmark is currently visible.
191
191
 
192
192
  ### `Deway.destroy()`
193
193
 
@@ -291,7 +291,7 @@ prerequisite calls were made.
291
291
 
292
292
  ### Bubble doesn't appear
293
293
 
294
- - Check `autoShowBubble` is set to `true` OR manually call `Deway.showBubble()`
294
+ - Check `autoShowBookmark` is set to `true` OR manually call `Deway.showBookmark()`
295
295
  - Verify `Deway.init()` was called with valid `appKey`
296
296
  - Check browser console for initialization errors
297
297
 
package/dist/loader.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { BubbleConfig } from '../deway-bubble/models/bubble-config';
1
+ import { BookmarkConfig } from '../deway-bookmark/models/bookmark-config';
2
2
  import { DewayConfig } from '../sdk/types';
3
3
  import { IDeway } from '../sdk/types';
4
4
 
5
- export { BubbleConfig }
5
+ export { BookmarkConfig }
6
6
 
7
7
  declare const Deway: IDeway;
8
8
  export default Deway;
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,9 @@ class S {
45
45
  getPromptSuggestions() {
46
46
  return this.loadConfig()?.promptSuggestions;
47
47
  }
48
+ getBookmarkAppearanceMode() {
49
+ return this.loadConfig()?.bookmarkAppearanceMode ?? "bookmark";
50
+ }
48
51
  }
49
52
  class s {
50
53
  static CACHE_KEY = "deway-sdk-cache";
@@ -53,9 +56,9 @@ class s {
53
56
  static STORE_NAME = "sdk";
54
57
  async cacheSDK(e, t, i, n) {
55
58
  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({
59
+ const d = (await this.openIndexedDB()).transaction([s.STORE_NAME], "readwrite").objectStore(s.STORE_NAME);
60
+ await new Promise((f, m) => {
61
+ const l = d.put({
59
62
  id: "latest",
60
63
  code: e,
61
64
  version: t,
@@ -63,27 +66,27 @@ class s {
63
66
  signature: n,
64
67
  timestamp: Date.now()
65
68
  });
66
- l.onsuccess = () => f(l.result), l.onerror = () => y(l.error);
69
+ l.onsuccess = () => f(l.result), l.onerror = () => m(l.error);
67
70
  });
68
71
  } catch {
69
72
  try {
70
- const a = JSON.stringify({
73
+ const o = JSON.stringify({
71
74
  code: e,
72
75
  version: t,
73
76
  checksum: i,
74
77
  signature: n,
75
78
  timestamp: Date.now()
76
79
  });
77
- localStorage.setItem(s.CACHE_KEY, a);
80
+ localStorage.setItem(s.CACHE_KEY, o);
78
81
  } catch {
79
82
  }
80
83
  }
81
84
  }
82
85
  async getCachedSDK() {
83
86
  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);
87
+ const i = (await this.openIndexedDB()).transaction([s.STORE_NAME], "readonly").objectStore(s.STORE_NAME), n = await new Promise((a, o) => {
88
+ const d = i.get("latest");
89
+ d.onsuccess = () => a(d.result || null), d.onerror = () => o(d.error);
87
90
  });
88
91
  if (n)
89
92
  return n;
@@ -101,15 +104,15 @@ class s {
101
104
  return new Promise((e, t) => {
102
105
  const i = indexedDB.open(s.DB_NAME, s.DB_VERSION);
103
106
  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" });
107
+ const a = n.target.result;
108
+ a.objectStoreNames.contains(s.STORE_NAME) || a.createObjectStore(s.STORE_NAME, { keyPath: "id" });
106
109
  };
107
110
  });
108
111
  }
109
112
  }
110
113
  async function C(r) {
111
114
  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("");
115
+ return Array.from(new Uint8Array(i)).map((a) => a.toString(16).padStart(2, "0")).join("");
113
116
  }
114
117
  function w(r) {
115
118
  const e = atob(r), t = new Uint8Array(e.length);
@@ -123,29 +126,29 @@ function E(r) {
123
126
  e[t / 2] = Number.parseInt(r.substr(t, 2), 16);
124
127
  return e;
125
128
  }
126
- async function b(r, e, t) {
129
+ async function D(r, e, t) {
127
130
  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);
131
+ const i = w(r), n = E(e), a = w(t), o = await crypto.subtle.importKey("raw", i, { name: "Ed25519" }, !1, ["verify"]);
132
+ return await crypto.subtle.verify("Ed25519", o, a, n);
130
133
  } catch {
131
134
  return !1;
132
135
  }
133
136
  }
134
- async function D(r, e, t, i) {
137
+ async function A(r, e, t, i) {
135
138
  if (!e || !t)
136
139
  throw new Error("SDK verification failed: Missing security headers");
137
140
  if (await C(r) !== e)
138
141
  throw new Error("SDK verification failed: Checksum mismatch - content tampered");
139
- if (!await b(i, e, t))
142
+ if (!await D(i, e, t))
140
143
  throw new Error("SDK verification failed: Invalid signature - content tampered");
141
144
  }
142
- class A {
145
+ class b {
143
146
  cleanApiEndpoint(e) {
144
147
  return e.trim().replace(/\/+$/, "");
145
148
  }
146
149
  async fetchSDK(e, t, i) {
147
150
  try {
148
- const n = this.cleanApiEndpoint(t), o = await fetch(`${n}/sdk-serve/sdk/v0`, {
151
+ const n = this.cleanApiEndpoint(t), a = await fetch(`${n}/sdk-serve/sdk/v0`, {
149
152
  method: "GET",
150
153
  headers: {
151
154
  Accept: "application/javascript",
@@ -153,23 +156,23 @@ class A {
153
156
  Origin: window?.location?.origin || ""
154
157
  }
155
158
  });
156
- return o.ok ? this.handleSuccessfulFetch(o, i) : null;
159
+ return a.ok ? this.handleSuccessfulFetch(a, i) : null;
157
160
  } catch {
158
161
  return null;
159
162
  }
160
163
  }
161
164
  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)
165
+ 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();
166
+ if (!n || !o || !i)
164
167
  throw Object.fromEntries(e.headers.entries()), new Error("Invalid SDK response: missing version, code, or checksum");
165
- return await D(a, i, o, t), { code: a, version: n, checksum: i, signature: o || "" };
168
+ return await A(o, i, a, t), { code: o, version: n, checksum: i, signature: a || "" };
166
169
  }
167
170
  }
168
- class m {
171
+ class g {
169
172
  static MAX_QUEUE_SIZE = 50;
170
173
  commandQueue = [];
171
174
  queueCommand(e, ...t) {
172
- this.commandQueue.length >= m.MAX_QUEUE_SIZE && this.commandQueue.shift(), this.commandQueue.push({ method: e, args: t });
175
+ this.commandQueue.length >= g.MAX_QUEUE_SIZE && this.commandQueue.shift(), this.commandQueue.push({ method: e, args: t });
173
176
  }
174
177
  replayQueuedCommands() {
175
178
  if (this.commandQueue.length === 0)
@@ -279,13 +282,13 @@ class K {
279
282
  const i = document.createElement("script");
280
283
  i.textContent = e, i.type = "text/javascript";
281
284
  let n = !1;
282
- const o = (a) => {
283
- n || (n = !0, this.cleanupScript(i), t(a));
285
+ const a = (o) => {
286
+ n || (n = !0, this.cleanupScript(i), t(o));
284
287
  };
285
288
  i.onerror = () => {
286
- o(!1);
287
- }, i.onload = () => o(!0), document.head.appendChild(i), setTimeout(() => {
288
- !n && this.verifySDKLoaded() ? o(!0) : n || o(!1);
289
+ a(!1);
290
+ }, i.onload = () => a(!0), document.head.appendChild(i), setTimeout(() => {
291
+ !n && this.verifySDKLoaded() ? a(!0) : n || a(!1);
289
292
  }, 100);
290
293
  } catch {
291
294
  t(!1);
@@ -319,11 +322,9 @@ class k {
319
322
  }
320
323
  const h = {
321
324
  apiEndpoint: "https://service.deway.app",
322
- publicKey: "9d3dBUvqyUQ7egd5j5uORdHSqZ7VFWOu+ud/SWt9WUY=",
323
- isDevelopment: !1,
324
- autoShowBubble: !1
325
+ publicKey: "9d3dBUvqyUQ7egd5j5uORdHSqZ7VFWOu+ud/SWt9WUY="
325
326
  };
326
- class B {
327
+ class I {
327
328
  isLoaded = !1;
328
329
  isLoading = !1;
329
330
  cacheManager;
@@ -335,7 +336,7 @@ class B {
335
336
  remoteConfigCache;
336
337
  sdkConfigStore;
337
338
  constructor() {
338
- this.cacheManager = new s(), this.scriptExecutor = new K(), this.commandQueue = new m(), this.sdkFetcher = new A(), this.configValidator = new k(), this.sdkConfigStore = new S(), this.remoteConfigFetcher = new v(), this.remoteConfigCache = new u();
339
+ 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
340
  }
340
341
  init(e) {
341
342
  this.performInit(e).catch((t) => {
@@ -349,11 +350,11 @@ class B {
349
350
  if (!this.configValidator.validateConfig(i))
350
351
  return;
351
352
  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)
353
+ const n = i.apiEndpoint || h.apiEndpoint, a = i.publicKey || h.publicKey, [o, d] = await Promise.all([this.fetchOrLoadSDK(i.appKey, n, a), this.fetchRemoteConfigWithCache(i, n)]);
354
+ if (!o)
354
355
  return;
355
- const f = t ? e : this.createInitializationPayload(c, i);
356
- if (!await this.scriptExecutor.executeSDK(a.code) || !this.initializeSDK(f))
356
+ const f = t ? e : this.createInitializationPayload(d, i);
357
+ if (!await this.scriptExecutor.executeSDK(o.code) || !this.initializeSDK(f))
357
358
  return;
358
359
  this.commandQueue.replayQueuedCommands(), this.isLoaded = !0;
359
360
  } finally {
@@ -428,21 +429,28 @@ class B {
428
429
  } catch {
429
430
  }
430
431
  }
431
- showBubble(e) {
432
+ show(e) {
433
+ try {
434
+ this.isLoaded && this.isSDKAvailable() ? window.Deway?.show(e) : this.commandQueue.queueCommand("show", e);
435
+ } catch {
436
+ }
437
+ }
438
+ hide() {
432
439
  try {
433
- this.isLoaded && this.isSDKAvailable() ? window.Deway?.showBubble(e) : this.commandQueue.queueCommand("showBubble", e);
440
+ this.isLoaded && this.isSDKAvailable() ? window.Deway?.hide() : this.commandQueue.queueCommand("hide");
434
441
  } catch {
435
442
  }
436
443
  }
437
- hideBubble() {
444
+ isVisible() {
438
445
  try {
439
- this.isLoaded && this.isSDKAvailable() ? window.Deway?.hideBubble() : this.commandQueue.queueCommand("hideBubble");
446
+ return this.isLoaded && this.isSDKAvailable() ? window.Deway?.isVisible() ?? !1 : !1;
440
447
  } catch {
448
+ return !1;
441
449
  }
442
450
  }
443
- isBubbleVisible() {
451
+ isInitialized() {
444
452
  try {
445
- return this.isLoaded && this.isSDKAvailable() ? window.Deway?.isBubbleVisible() ?? !1 : !1;
453
+ return this.isLoaded && this.isSDKAvailable() ? window.Deway?.isInitialized() ?? !1 : !1;
446
454
  } catch {
447
455
  return !1;
448
456
  }
@@ -457,15 +465,16 @@ class B {
457
465
  return typeof window < "u" && "Deway" in window && !!window.Deway;
458
466
  }
459
467
  }
460
- const d = new B(), x = {
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
- showBubble: (r) => d.showBubble(r),
466
- hideBubble: () => d.hideBubble(),
467
- isBubbleVisible: () => d.isBubbleVisible(),
468
- destroy: () => d.destroy()
468
+ const c = new I(), x = {
469
+ init: (r) => c.init(r),
470
+ identify: (r) => c.identify(r),
471
+ reportEvent: (r, e) => c.reportEvent(r, e),
472
+ setUserProfile: (r) => c.setUserProfile(r),
473
+ show: (r) => c.show(r),
474
+ hide: () => c.hide(),
475
+ isVisible: () => c.isVisible(),
476
+ isInitialized: () => c.isInitialized(),
477
+ destroy: () => c.destroy()
469
478
  };
470
479
  typeof window < "u" && (window.Deway = x);
471
480
  export {
@@ -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 b(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 D(r,e,t){try{const i=w(r),n=b(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 A(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 D(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 A(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,autoShowBubble:!1};class B{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 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{}}showBubble(e){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.showBubble(e):this.commandQueue.queueCommand("showBubble",e)}catch{}}hideBubble(){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.hideBubble():this.commandQueue.queueCommand("hideBubble")}catch{}}isBubbleVisible(){try{return this.isLoaded&&this.isSDKAvailable()?window.Deway?.isBubbleVisible()??!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 B,p={init:r=>c.init(r),identify:r=>c.identify(r),reportEvent:(r,e)=>c.reportEvent(r,e),setUserProfile:r=>c.setUserProfile(r),showBubble:r=>c.showBubble(r),hideBubble:()=>c.hideBubble(),isBubbleVisible:()=>c.isBubbleVisible(),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"}}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 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 I{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="};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 m,this.sdkFetcher=new v,this.configValidator=new I,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}}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: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.41.0",
3
+ "version": "0.43.0",
4
4
  "type": "module",
5
5
  "description": "Deway's Web SDK",
6
6
  "main": "dist/loader.umd.js",