@deway-ai/web-sdk 0.40.0 → 0.42.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 w = "deway-sdk-config", p = ["Understanding intent", "Reading web page", "Browsing the docs", "Enriching context", "Validating understanding", "Crafting response"];
1
+ const g = "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(w, t);
7
+ window.localStorage.setItem(g, 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(w);
14
+ const e = window.localStorage.getItem(g);
15
15
  return e ? JSON.parse(e) : null;
16
16
  } catch {
17
17
  return null;
@@ -42,6 +42,9 @@ class S {
42
42
  getFeatureFlag(e) {
43
43
  return this.getFeatureFlags()[e] ?? !1;
44
44
  }
45
+ getPromptSuggestions() {
46
+ return this.loadConfig()?.promptSuggestions;
47
+ }
45
48
  }
46
49
  class s {
47
50
  static CACHE_KEY = "deway-sdk-cache";
@@ -51,7 +54,7 @@ class s {
51
54
  async cacheSDK(e, t, i, n) {
52
55
  try {
53
56
  const c = (await this.openIndexedDB()).transaction([s.STORE_NAME], "readwrite").objectStore(s.STORE_NAME);
54
- await new Promise((h, m) => {
57
+ await new Promise((f, y) => {
55
58
  const l = c.put({
56
59
  id: "latest",
57
60
  code: e,
@@ -60,27 +63,27 @@ class s {
60
63
  signature: n,
61
64
  timestamp: Date.now()
62
65
  });
63
- l.onsuccess = () => h(l.result), l.onerror = () => m(l.error);
66
+ l.onsuccess = () => f(l.result), l.onerror = () => y(l.error);
64
67
  });
65
68
  } catch {
66
69
  try {
67
- const o = JSON.stringify({
70
+ const a = JSON.stringify({
68
71
  code: e,
69
72
  version: t,
70
73
  checksum: i,
71
74
  signature: n,
72
75
  timestamp: Date.now()
73
76
  });
74
- localStorage.setItem(s.CACHE_KEY, o);
77
+ localStorage.setItem(s.CACHE_KEY, a);
75
78
  } catch {
76
79
  }
77
80
  }
78
81
  }
79
82
  async getCachedSDK() {
80
83
  try {
81
- const i = (await this.openIndexedDB()).transaction([s.STORE_NAME], "readonly").objectStore(s.STORE_NAME), n = await new Promise((a, o) => {
84
+ const i = (await this.openIndexedDB()).transaction([s.STORE_NAME], "readonly").objectStore(s.STORE_NAME), n = await new Promise((o, a) => {
82
85
  const c = i.get("latest");
83
- c.onsuccess = () => a(c.result || null), c.onerror = () => o(c.error);
86
+ c.onsuccess = () => o(c.result || null), c.onerror = () => a(c.error);
84
87
  });
85
88
  if (n)
86
89
  return n;
@@ -98,17 +101,17 @@ class s {
98
101
  return new Promise((e, t) => {
99
102
  const i = indexedDB.open(s.DB_NAME, s.DB_VERSION);
100
103
  i.onerror = () => t(i.error), i.onsuccess = () => e(i.result), i.onupgradeneeded = (n) => {
101
- const a = n.target.result;
102
- a.objectStoreNames.contains(s.STORE_NAME) || a.createObjectStore(s.STORE_NAME, { keyPath: "id" });
104
+ const o = n.target.result;
105
+ o.objectStoreNames.contains(s.STORE_NAME) || o.createObjectStore(s.STORE_NAME, { keyPath: "id" });
103
106
  };
104
107
  });
105
108
  }
106
109
  }
107
110
  async function C(r) {
108
111
  const t = new TextEncoder().encode(r), i = await crypto.subtle.digest("SHA-256", t);
109
- return Array.from(new Uint8Array(i)).map((a) => a.toString(16).padStart(2, "0")).join("");
112
+ return Array.from(new Uint8Array(i)).map((o) => o.toString(16).padStart(2, "0")).join("");
110
113
  }
111
- function g(r) {
114
+ function w(r) {
112
115
  const e = atob(r), t = new Uint8Array(e.length);
113
116
  for (let i = 0; i < e.length; i++)
114
117
  t[i] = e.charCodeAt(i);
@@ -120,29 +123,29 @@ function E(r) {
120
123
  e[t / 2] = Number.parseInt(r.substr(t, 2), 16);
121
124
  return e;
122
125
  }
123
- async function b(r, e, t) {
126
+ async function D(r, e, t) {
124
127
  try {
125
- const i = g(r), n = E(e), a = g(t), o = await crypto.subtle.importKey("raw", i, { name: "Ed25519" }, !1, ["verify"]);
126
- return await crypto.subtle.verify("Ed25519", o, a, n);
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);
127
130
  } catch {
128
131
  return !1;
129
132
  }
130
133
  }
131
- async function D(r, e, t, i) {
134
+ async function A(r, e, t, i) {
132
135
  if (!e || !t)
133
136
  throw new Error("SDK verification failed: Missing security headers");
134
137
  if (await C(r) !== e)
135
138
  throw new Error("SDK verification failed: Checksum mismatch - content tampered");
136
- if (!await b(i, e, t))
139
+ if (!await D(i, e, t))
137
140
  throw new Error("SDK verification failed: Invalid signature - content tampered");
138
141
  }
139
- class A {
142
+ class v {
140
143
  cleanApiEndpoint(e) {
141
144
  return e.trim().replace(/\/+$/, "");
142
145
  }
143
146
  async fetchSDK(e, t, i) {
144
147
  try {
145
- const n = this.cleanApiEndpoint(t), a = await fetch(`${n}/sdk-serve/sdk/v0`, {
148
+ const n = this.cleanApiEndpoint(t), o = await fetch(`${n}/sdk-serve/sdk/v0`, {
146
149
  method: "GET",
147
150
  headers: {
148
151
  Accept: "application/javascript",
@@ -150,23 +153,23 @@ class A {
150
153
  Origin: window?.location?.origin || ""
151
154
  }
152
155
  });
153
- return a.ok ? this.handleSuccessfulFetch(a, i) : null;
156
+ return o.ok ? this.handleSuccessfulFetch(o, i) : null;
154
157
  } catch {
155
158
  return null;
156
159
  }
157
160
  }
158
161
  async handleSuccessfulFetch(e, t) {
159
- 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();
160
- if (!n || !o || !i)
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)
161
164
  throw Object.fromEntries(e.headers.entries()), new Error("Invalid SDK response: missing version, code, or checksum");
162
- return await D(o, i, a, t), { code: o, version: n, checksum: i, signature: a || "" };
165
+ return await A(a, i, o, t), { code: a, version: n, checksum: i, signature: o || "" };
163
166
  }
164
167
  }
165
- class y {
168
+ class m {
166
169
  static MAX_QUEUE_SIZE = 50;
167
170
  commandQueue = [];
168
171
  queueCommand(e, ...t) {
169
- this.commandQueue.length >= y.MAX_QUEUE_SIZE && this.commandQueue.shift(), this.commandQueue.push({ method: e, args: t });
172
+ this.commandQueue.length >= m.MAX_QUEUE_SIZE && this.commandQueue.shift(), this.commandQueue.push({ method: e, args: t });
170
173
  }
171
174
  replayQueuedCommands() {
172
175
  if (this.commandQueue.length === 0)
@@ -237,7 +240,7 @@ class u {
237
240
  return i < n;
238
241
  }
239
242
  }
240
- class v {
243
+ class b {
241
244
  cleanApiEndpoint(e) {
242
245
  return e.trim().replace(/\/+$/, "");
243
246
  }
@@ -276,13 +279,13 @@ class K {
276
279
  const i = document.createElement("script");
277
280
  i.textContent = e, i.type = "text/javascript";
278
281
  let n = !1;
279
- const a = (o) => {
280
- n || (n = !0, this.cleanupScript(i), t(o));
282
+ const o = (a) => {
283
+ n || (n = !0, this.cleanupScript(i), t(a));
281
284
  };
282
285
  i.onerror = () => {
283
- a(!1);
284
- }, i.onload = () => a(!0), document.head.appendChild(i), setTimeout(() => {
285
- !n && this.verifySDKLoaded() ? a(!0) : n || a(!1);
286
+ o(!1);
287
+ }, i.onload = () => o(!0), document.head.appendChild(i), setTimeout(() => {
288
+ !n && this.verifySDKLoaded() ? o(!0) : n || o(!1);
286
289
  }, 100);
287
290
  } catch {
288
291
  t(!1);
@@ -314,13 +317,13 @@ class k {
314
317
  }
315
318
  }
316
319
  }
317
- const f = {
320
+ const h = {
318
321
  apiEndpoint: "https://service.deway.app",
319
322
  publicKey: "9d3dBUvqyUQ7egd5j5uORdHSqZ7VFWOu+ud/SWt9WUY=",
320
323
  isDevelopment: !1,
321
- autoShowBubble: !1
324
+ autoShowBookmark: !1
322
325
  };
323
- class B {
326
+ class x {
324
327
  isLoaded = !1;
325
328
  isLoading = !1;
326
329
  cacheManager;
@@ -332,7 +335,7 @@ class B {
332
335
  remoteConfigCache;
333
336
  sdkConfigStore;
334
337
  constructor() {
335
- this.cacheManager = new s(), this.scriptExecutor = new K(), this.commandQueue = new y(), this.sdkFetcher = new A(), this.configValidator = new k(), this.sdkConfigStore = new S(), this.remoteConfigFetcher = new v(), this.remoteConfigCache = new u();
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();
336
339
  }
337
340
  init(e) {
338
341
  this.performInit(e).catch((t) => {
@@ -346,11 +349,11 @@ class B {
346
349
  if (!this.configValidator.validateConfig(i))
347
350
  return;
348
351
  this.isLoading = !0;
349
- const n = i.apiEndpoint || f.apiEndpoint, a = i.publicKey || f.publicKey, [o, c] = await Promise.all([this.fetchOrLoadSDK(i.appKey, n, a), this.fetchRemoteConfigWithCache(i, n)]);
350
- if (!o)
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)
351
354
  return;
352
- const h = t ? e : this.createInitializationPayload(c, i);
353
- if (!await this.scriptExecutor.executeSDK(o.code) || !this.initializeSDK(h))
355
+ const f = t ? e : this.createInitializationPayload(c, i);
356
+ if (!await this.scriptExecutor.executeSDK(a.code) || !this.initializeSDK(f))
354
357
  return;
355
358
  this.commandQueue.replayQueuedCommands(), this.isLoaded = !0;
356
359
  } finally {
@@ -387,7 +390,7 @@ class B {
387
390
  return {
388
391
  localConfig: t,
389
392
  remoteConfig: e?.config ?? null,
390
- defaults: f
393
+ defaults: h
391
394
  };
392
395
  }
393
396
  async fetchOrLoadSDK(e, t, i) {
@@ -425,21 +428,21 @@ class B {
425
428
  } catch {
426
429
  }
427
430
  }
428
- showBubble(e) {
431
+ show(e) {
429
432
  try {
430
- this.isLoaded && this.isSDKAvailable() ? window.Deway?.showBubble(e) : this.commandQueue.queueCommand("showBubble", e);
433
+ this.isLoaded && this.isSDKAvailable() ? window.Deway?.show(e) : this.commandQueue.queueCommand("show", e);
431
434
  } catch {
432
435
  }
433
436
  }
434
- hideBubble() {
437
+ hide() {
435
438
  try {
436
- this.isLoaded && this.isSDKAvailable() ? window.Deway?.hideBubble() : this.commandQueue.queueCommand("hideBubble");
439
+ this.isLoaded && this.isSDKAvailable() ? window.Deway?.hide() : this.commandQueue.queueCommand("hide");
437
440
  } catch {
438
441
  }
439
442
  }
440
- isBubbleVisible() {
443
+ isVisible() {
441
444
  try {
442
- return this.isLoaded && this.isSDKAvailable() ? window.Deway?.isBubbleVisible() ?? !1 : !1;
445
+ return this.isLoaded && this.isSDKAvailable() ? window.Deway?.isVisible() ?? !1 : !1;
443
446
  } catch {
444
447
  return !1;
445
448
  }
@@ -454,17 +457,17 @@ class B {
454
457
  return typeof window < "u" && "Deway" in window && !!window.Deway;
455
458
  }
456
459
  }
457
- const d = new B(), x = {
460
+ const d = new x(), I = {
458
461
  init: (r) => d.init(r),
459
462
  identify: (r) => d.identify(r),
460
463
  reportEvent: (r, e) => d.reportEvent(r, e),
461
464
  setUserProfile: (r) => d.setUserProfile(r),
462
- showBubble: (r) => d.showBubble(r),
463
- hideBubble: () => d.hideBubble(),
464
- isBubbleVisible: () => d.isBubbleVisible(),
465
+ show: (r) => d.show(r),
466
+ hide: () => d.hide(),
467
+ isVisible: () => d.isVisible(),
465
468
  destroy: () => d.destroy()
466
469
  };
467
- typeof window < "u" && (window.Deway = x);
470
+ typeof window < "u" && (window.Deway = I);
468
471
  export {
469
- x as default
472
+ I as default
470
473
  };
@@ -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}}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((w,S)=>{const f=d.put({id:"latest",code:e,version:t,checksum:i,signature:n,timestamp:Date.now()});f.onsuccess=()=>w(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 g(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=g(r),n=b(e),o=g(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 y{static MAX_QUEUE_SIZE=50;commandQueue=[];queueCommand(e,...t){this.commandQueue.length>=y.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 m={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 y,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||m.apiEndpoint,o=i.publicKey||m.publicKey,[a,d]=await Promise.all([this.fetchOrLoadSDK(i.appKey,n,o),this.fetchRemoteConfigWithCache(i,n)]);if(!a)return;const w=t?e:this.createInitializationPayload(d,i);if(!await this.scriptExecutor.executeSDK(a.code)||!this.initializeSDK(w))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:m}}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}}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}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deway-ai/web-sdk",
3
- "version": "0.40.0",
3
+ "version": "0.42.0",
4
4
  "type": "module",
5
5
  "description": "Deway's Web SDK",
6
6
  "main": "dist/loader.umd.js",