@deway-ai/web-sdk 0.66.0 → 0.68.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
@@ -224,6 +224,39 @@ document.getElementById('logout-button').addEventListener('click', () => {
224
224
  - Can be called immediately after reset to identify a new user
225
225
  - Safe to call multiple times
226
226
 
227
+ ### `Deway.registerSupportCallback(callback)`
228
+
229
+ Register a custom callback that fires when the user clicks the "Talk to Support" button in the chat interface. Overwrites any previously registered callback.
230
+
231
+ **Parameters:**
232
+
233
+ - `callback` (() => void | Promise\<void\>): Function called when the support button is clicked. If it throws or returns a rejected Promise, Deway falls back to the remotely configured support behavior (URL redirect or selector guide).
234
+
235
+ **Example:**
236
+
237
+ ```typescript
238
+ Deway.registerSupportCallback(async () => {
239
+ // Open your own support widget
240
+ await openChat();
241
+ });
242
+ ```
243
+
244
+ **Notes:**
245
+
246
+ - Only one callback can be active at a time — subsequent calls replace the previous one
247
+ - If the callback throws or rejects, Deway automatically falls back to the server-configured support mode
248
+ - Call `Deway.unregisterSupportCallback()` to restore default server-configured behavior
249
+
250
+ ### `Deway.unregisterSupportCallback()`
251
+
252
+ Remove the registered support callback and restore the default server-configured support behavior (URL redirect or selector guide).
253
+
254
+ **Example:**
255
+
256
+ ```typescript
257
+ Deway.unregisterSupportCallback();
258
+ ```
259
+
227
260
  ### `Deway.destroy()`
228
261
 
229
262
  Clean up SDK resources and stop all tracking.
package/dist/loader.es.js CHANGED
@@ -1,4 +1,4 @@
1
- const y = "deway-sdk-config", p = ["Understanding intent", "Reading web page", "Browsing the docs", "Enriching context", "Validating understanding", "Crafting response"];
1
+ const y = "deway-sdk-config", w = ["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)
@@ -28,7 +28,7 @@ class S {
28
28
  return this.loadConfig()?.aiDisclaimer;
29
29
  }
30
30
  getThinkingMessages() {
31
- return this.loadConfig()?.thinkingMessages ?? p;
31
+ return this.loadConfig()?.thinkingMessages ?? w;
32
32
  }
33
33
  /**
34
34
  * Get the support handoff configuration
@@ -96,21 +96,21 @@ class S {
96
96
  return this.getUIAlignment()?.side ?? "right";
97
97
  }
98
98
  }
99
- class s {
99
+ class c {
100
100
  static CACHE_KEY = "deway-sdk-cache";
101
101
  static DB_NAME = "DewaySdk";
102
102
  static DB_VERSION = 1;
103
103
  static STORE_NAME = "sdk";
104
- async cacheSDK(e, t, n, i) {
104
+ async cacheSDK(e, t, i, n) {
105
105
  try {
106
- const d = (await this.openIndexedDB()).transaction([s.STORE_NAME], "readwrite").objectStore(s.STORE_NAME);
106
+ const d = (await this.openIndexedDB()).transaction([c.STORE_NAME], "readwrite").objectStore(c.STORE_NAME);
107
107
  await new Promise((h, m) => {
108
108
  const l = d.put({
109
109
  id: "latest",
110
110
  code: e,
111
111
  version: t,
112
- checksum: n,
113
- signature: i,
112
+ checksum: i,
113
+ signature: n,
114
114
  timestamp: Date.now()
115
115
  });
116
116
  l.onsuccess = () => h(l.result), l.onerror = () => m(l.error);
@@ -120,27 +120,27 @@ class s {
120
120
  const a = JSON.stringify({
121
121
  code: e,
122
122
  version: t,
123
- checksum: n,
124
- signature: i,
123
+ checksum: i,
124
+ signature: n,
125
125
  timestamp: Date.now()
126
126
  });
127
- localStorage.setItem(s.CACHE_KEY, a);
127
+ localStorage.setItem(c.CACHE_KEY, a);
128
128
  } catch {
129
129
  }
130
130
  }
131
131
  }
132
132
  async getCachedSDK() {
133
133
  try {
134
- const n = (await this.openIndexedDB()).transaction([s.STORE_NAME], "readonly").objectStore(s.STORE_NAME), i = await new Promise((r, a) => {
135
- const d = n.get("latest");
134
+ const i = (await this.openIndexedDB()).transaction([c.STORE_NAME], "readonly").objectStore(c.STORE_NAME), n = await new Promise((r, a) => {
135
+ const d = i.get("latest");
136
136
  d.onsuccess = () => r(d.result || null), d.onerror = () => a(d.error);
137
137
  });
138
- if (i)
139
- return i;
138
+ if (n)
139
+ return n;
140
140
  } catch {
141
141
  }
142
142
  try {
143
- const e = localStorage.getItem(s.CACHE_KEY);
143
+ const e = localStorage.getItem(c.CACHE_KEY);
144
144
  if (e)
145
145
  return JSON.parse(e);
146
146
  } catch {
@@ -149,22 +149,22 @@ class s {
149
149
  }
150
150
  openIndexedDB() {
151
151
  return new Promise((e, t) => {
152
- const n = indexedDB.open(s.DB_NAME, s.DB_VERSION);
153
- n.onerror = () => t(n.error), n.onsuccess = () => e(n.result), n.onupgradeneeded = (i) => {
154
- const r = i.target.result;
155
- r.objectStoreNames.contains(s.STORE_NAME) || r.createObjectStore(s.STORE_NAME, { keyPath: "id" });
152
+ const i = indexedDB.open(c.DB_NAME, c.DB_VERSION);
153
+ i.onerror = () => t(i.error), i.onsuccess = () => e(i.result), i.onupgradeneeded = (n) => {
154
+ const r = n.target.result;
155
+ r.objectStoreNames.contains(c.STORE_NAME) || r.createObjectStore(c.STORE_NAME, { keyPath: "id" });
156
156
  };
157
157
  });
158
158
  }
159
159
  }
160
160
  async function C(o) {
161
- const t = new TextEncoder().encode(o), n = await crypto.subtle.digest("SHA-256", t);
162
- return Array.from(new Uint8Array(n)).map((r) => r.toString(16).padStart(2, "0")).join("");
161
+ const t = new TextEncoder().encode(o), i = await crypto.subtle.digest("SHA-256", t);
162
+ return Array.from(new Uint8Array(i)).map((r) => r.toString(16).padStart(2, "0")).join("");
163
163
  }
164
- function w(o) {
164
+ function p(o) {
165
165
  const e = atob(o), t = new Uint8Array(e.length);
166
- for (let n = 0; n < e.length; n++)
167
- t[n] = e.charCodeAt(n);
166
+ for (let i = 0; i < e.length; i++)
167
+ t[i] = e.charCodeAt(i);
168
168
  return t;
169
169
  }
170
170
  function E(o) {
@@ -175,27 +175,27 @@ function E(o) {
175
175
  }
176
176
  async function D(o, e, t) {
177
177
  try {
178
- const n = w(o), i = E(e), r = w(t), a = await crypto.subtle.importKey("raw", n, { name: "Ed25519" }, !1, ["verify"]);
179
- return await crypto.subtle.verify("Ed25519", a, r, i);
178
+ const i = p(o), n = E(e), r = p(t), a = await crypto.subtle.importKey("raw", i, { name: "Ed25519" }, !1, ["verify"]);
179
+ return await crypto.subtle.verify("Ed25519", a, r, n);
180
180
  } catch {
181
181
  return !1;
182
182
  }
183
183
  }
184
- async function A(o, e, t, n) {
184
+ async function A(o, e, t, i) {
185
185
  if (!e || !t)
186
186
  throw new Error("SDK verification failed: Missing security headers");
187
187
  if (await C(o) !== e)
188
188
  throw new Error("SDK verification failed: Checksum mismatch - content tampered");
189
- if (!await D(n, e, t))
189
+ if (!await D(i, e, t))
190
190
  throw new Error("SDK verification failed: Invalid signature - content tampered");
191
191
  }
192
- class v {
192
+ class b {
193
193
  cleanApiEndpoint(e) {
194
194
  return e.trim().replace(/\/+$/, "");
195
195
  }
196
- async fetchSDK(e, t, n) {
196
+ async fetchSDK(e, t, i) {
197
197
  try {
198
- const i = this.cleanApiEndpoint(t), r = await fetch(`${i}/sdk-serve/sdk/v0`, {
198
+ const n = this.cleanApiEndpoint(t), r = await fetch(`${n}/sdk-serve/sdk/v0`, {
199
199
  method: "GET",
200
200
  headers: {
201
201
  Accept: "application/javascript",
@@ -203,16 +203,16 @@ class v {
203
203
  Origin: window?.location?.origin || ""
204
204
  }
205
205
  });
206
- return r.ok ? this.handleSuccessfulFetch(r, n) : null;
206
+ return r.ok ? this.handleSuccessfulFetch(r, i) : null;
207
207
  } catch {
208
208
  return null;
209
209
  }
210
210
  }
211
211
  async handleSuccessfulFetch(e, t) {
212
- const n = e.headers.get("x-sdk-checksum"), i = e.headers.get("x-sdk-version"), r = e.headers.get("x-sdk-signature"), a = await e.text();
213
- if (!i || !a || !n)
212
+ const i = e.headers.get("x-sdk-checksum"), n = e.headers.get("x-sdk-version"), r = e.headers.get("x-sdk-signature"), a = await e.text();
213
+ if (!n || !a || !i)
214
214
  throw Object.fromEntries(e.headers.entries()), new Error("Invalid SDK response: missing version, code, or checksum");
215
- return await A(a, n, r, t), { code: a, version: i, checksum: n, signature: r || "" };
215
+ return await A(a, i, r, t), { code: a, version: n, checksum: i, signature: r || "" };
216
216
  }
217
217
  }
218
218
  class g {
@@ -237,8 +237,8 @@ class g {
237
237
  }
238
238
  replayCommand(e) {
239
239
  try {
240
- const t = window.Deway, n = t?.[e.method];
241
- typeof n == "function" && n.apply(t, e.args);
240
+ const t = window.Deway, i = t?.[e.method];
241
+ typeof i == "function" && i.apply(t, e.args);
242
242
  } catch {
243
243
  }
244
244
  }
@@ -254,12 +254,12 @@ class u {
254
254
  */
255
255
  async cacheRemoteConfig(e, t) {
256
256
  try {
257
- const n = {
257
+ const i = {
258
258
  config: e,
259
259
  ttl_seconds: t,
260
260
  timestamp: Date.now()
261
261
  };
262
- localStorage.setItem(u.CACHE_KEY, JSON.stringify(n));
262
+ localStorage.setItem(u.CACHE_KEY, JSON.stringify(i));
263
263
  } catch {
264
264
  }
265
265
  }
@@ -286,11 +286,11 @@ class u {
286
286
  * @returns true if cache is still valid
287
287
  */
288
288
  isCacheValid(e, t) {
289
- const n = Date.now(), i = e + t * 1e3;
290
- return n < i;
289
+ const i = Date.now(), n = e + t * 1e3;
290
+ return i < n;
291
291
  }
292
292
  }
293
- class I {
293
+ class v {
294
294
  cleanApiEndpoint(e) {
295
295
  return e.trim().replace(/\/+$/, "");
296
296
  }
@@ -304,7 +304,7 @@ class I {
304
304
  */
305
305
  async fetchRemoteConfig(e, t) {
306
306
  try {
307
- const n = this.cleanApiEndpoint(t), i = await fetch(`${n}/sdk-remote-config-serve/`, {
307
+ const i = this.cleanApiEndpoint(t), n = await fetch(`${i}/sdk-remote-config-serve/`, {
308
308
  method: "GET",
309
309
  headers: {
310
310
  Accept: "application/json",
@@ -312,13 +312,13 @@ class I {
312
312
  Origin: window?.location?.origin || ""
313
313
  }
314
314
  });
315
- return i.ok ? await i.json() : null;
315
+ return n.ok ? await n.json() : null;
316
316
  } catch {
317
317
  return null;
318
318
  }
319
319
  }
320
320
  }
321
- class b {
321
+ class I {
322
322
  async executeSDK(e) {
323
323
  return new Promise((t) => {
324
324
  try {
@@ -326,16 +326,16 @@ class b {
326
326
  t(!1);
327
327
  return;
328
328
  }
329
- const n = document.createElement("script");
330
- n.textContent = e, n.type = "text/javascript";
331
- let i = !1;
329
+ const i = document.createElement("script");
330
+ i.textContent = e, i.type = "text/javascript";
331
+ let n = !1;
332
332
  const r = (a) => {
333
- i || (i = !0, this.cleanupScript(n), t(a));
333
+ n || (n = !0, this.cleanupScript(i), t(a));
334
334
  };
335
- n.onerror = () => {
335
+ i.onerror = () => {
336
336
  r(!1);
337
- }, n.onload = () => r(!0), document.head.appendChild(n), setTimeout(() => {
338
- !i && this.verifySDKLoaded() ? r(!0) : i || r(!1);
337
+ }, i.onload = () => r(!0), document.head.appendChild(i), setTimeout(() => {
338
+ !n && this.verifySDKLoaded() ? r(!0) : n || r(!1);
339
339
  }, 100);
340
340
  } catch {
341
341
  t(!1);
@@ -383,7 +383,7 @@ class k {
383
383
  remoteConfigCache;
384
384
  sdkConfigStore;
385
385
  constructor() {
386
- this.cacheManager = new s(), this.scriptExecutor = new b(), this.commandQueue = new g(), this.sdkFetcher = new v(), this.configValidator = new K(), this.sdkConfigStore = new S(), this.remoteConfigFetcher = new I(), this.remoteConfigCache = new u();
386
+ this.cacheManager = new c(), this.scriptExecutor = new I(), this.commandQueue = new g(), this.sdkFetcher = new b(), this.configValidator = new K(), this.sdkConfigStore = new S(), this.remoteConfigFetcher = new v(), this.remoteConfigCache = new u();
387
387
  }
388
388
  init(e) {
389
389
  this.performInit(e).catch((t) => {
@@ -393,14 +393,14 @@ class k {
393
393
  try {
394
394
  if (!this.canInitialize())
395
395
  return;
396
- const t = this.isInitializationPayload(e), n = t ? e.localConfig : e;
397
- if (!this.configValidator.validateConfig(n))
396
+ const t = this.isInitializationPayload(e), i = t ? e.localConfig : e;
397
+ if (!this.configValidator.validateConfig(i))
398
398
  return;
399
399
  this.isLoading = !0;
400
- const i = n.apiEndpoint || f.apiEndpoint, r = n.publicKey || f.publicKey, [a, d] = await Promise.all([this.fetchOrLoadSDK(n.appKey, i, r), this.fetchRemoteConfigWithCache(n, i)]);
400
+ const n = i.apiEndpoint || f.apiEndpoint, r = i.publicKey || f.publicKey, [a, d] = await Promise.all([this.fetchOrLoadSDK(i.appKey, n, r), this.fetchRemoteConfigWithCache(i, n)]);
401
401
  if (!a)
402
402
  return;
403
- const h = t ? e : this.createInitializationPayload(d, n);
403
+ const h = t ? e : this.createInitializationPayload(d, i);
404
404
  if (!await this.scriptExecutor.executeSDK(a.code) || !this.initializeSDK(h))
405
405
  return;
406
406
  this.commandQueue.replayQueuedCommands(), this.isLoaded = !0;
@@ -420,13 +420,13 @@ class k {
420
420
  */
421
421
  async fetchRemoteConfigWithCache(e, t) {
422
422
  this.sdkConfigStore.saveConfig(e);
423
- const n = await this.remoteConfigFetcher.fetchRemoteConfig(e.appKey, t);
424
- if (n)
425
- return await this.remoteConfigCache.cacheRemoteConfig(n.config, n.ttl_seconds), n;
426
- const i = await this.remoteConfigCache.getCachedRemoteConfig();
427
- return i ? {
428
- config: i.config,
429
- ttl_seconds: i.ttl_seconds
423
+ const i = await this.remoteConfigFetcher.fetchRemoteConfig(e.appKey, t);
424
+ if (i)
425
+ return await this.remoteConfigCache.cacheRemoteConfig(i.config, i.ttl_seconds), i;
426
+ const n = await this.remoteConfigCache.getCachedRemoteConfig();
427
+ return n ? {
428
+ config: n.config,
429
+ ttl_seconds: n.ttl_seconds
430
430
  } : null;
431
431
  }
432
432
  /**
@@ -441,9 +441,9 @@ class k {
441
441
  defaults: f
442
442
  };
443
443
  }
444
- async fetchOrLoadSDK(e, t, n) {
445
- const i = await this.sdkFetcher.fetchSDK(e, t, n);
446
- return i ? (await this.cacheManager.cacheSDK(i.code, i.version, i.checksum, i.signature), i) : this.loadFromCache();
444
+ async fetchOrLoadSDK(e, t, i) {
445
+ const n = await this.sdkFetcher.fetchSDK(e, t, i);
446
+ return n ? (await this.cacheManager.cacheSDK(n.code, n.version, n.checksum, n.signature), n) : this.loadFromCache();
447
447
  }
448
448
  async loadFromCache() {
449
449
  const e = await this.cacheManager.getCachedSDK();
@@ -514,6 +514,18 @@ class k {
514
514
  return !1;
515
515
  }
516
516
  }
517
+ registerSupportCallback(e) {
518
+ try {
519
+ this.isLoaded && this.isSDKAvailable() ? window.Deway?.registerSupportCallback(e) : this.commandQueue.queueCommand("registerSupportCallback", e);
520
+ } catch {
521
+ }
522
+ }
523
+ unregisterSupportCallback() {
524
+ try {
525
+ this.isLoaded && this.isSDKAvailable() ? window.Deway?.unregisterSupportCallback() : this.commandQueue.queueCommand("unregisterSupportCallback");
526
+ } catch {
527
+ }
528
+ }
517
529
  destroy() {
518
530
  try {
519
531
  this.isLoaded && this.isSDKAvailable() ? window.Deway?.destroy() : this.commandQueue.queueCommand("destroy"), this.commandQueue.clearQueue();
@@ -524,18 +536,20 @@ class k {
524
536
  return typeof window < "u" && "Deway" in window && !!window.Deway;
525
537
  }
526
538
  }
527
- const c = new k(), _ = {
528
- init: (o) => c.init(o),
529
- identify: (o) => c.identify(o),
530
- reportEvent: (o, e) => c.reportEvent(o, e),
531
- setUserProfile: (o) => c.setUserProfile(o),
532
- show: (o) => c.show(o),
533
- hide: () => c.hide(),
534
- openChat: () => c.openChat(),
535
- resetUserLocally: () => c.resetUserLocally(),
536
- isVisible: () => c.isVisible(),
537
- isInitialized: () => c.isInitialized(),
538
- destroy: () => c.destroy()
539
+ const s = new k(), _ = {
540
+ init: (o) => s.init(o),
541
+ identify: (o) => s.identify(o),
542
+ reportEvent: (o, e) => s.reportEvent(o, e),
543
+ setUserProfile: (o) => s.setUserProfile(o),
544
+ show: (o) => s.show(o),
545
+ hide: () => s.hide(),
546
+ openChat: () => s.openChat(),
547
+ resetUserLocally: () => s.resetUserLocally(),
548
+ registerSupportCallback: (o) => s.registerSupportCallback(o),
549
+ unregisterSupportCallback: () => s.unregisterSupportCallback(),
550
+ isVisible: () => s.isVisible(),
551
+ isInitialized: () => s.isInitialized(),
552
+ destroy: () => s.destroy()
539
553
  };
540
554
  typeof window < "u" && (window.Deway = _);
541
555
  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}getSupportHandoff(){return this.loadConfig()?.supportHandoff??null}getSupportHandoffButtonText(){return this.getSupportHandoff()?.button_text??"talk to Support"}getFeatureFlags(){return this.loadConfig()?.featureFlags??{}}getFeatureFlag(e){return this.getFeatureFlags()[e]??!1}getPromptSuggestions(){return this.loadConfig()?.promptSuggestions}getWelcomeTitle(){return this.loadConfig()?.welcomeTitle??"How can I help you today?"}getWelcomeSubtitle(){return this.loadConfig()?.welcomeSubtitle??"I'm ready to help you navigate, learn, and get things done."}getEntrypointWidgetAppearanceMode(){return this.loadConfig()?.entrypointWidgetAppearanceMode??"bookmark"}getTenantTheme(){return this.loadConfig()?.tenantTheme??null}getTenantThemeForMode(e){const t=this.getTenantTheme();return t?e==="dark"?t.dark:t.light:null}getCustomIcons(){return this.loadConfig()?.customIcons??null}getEntrypointWidgetIconInlineSvg(){return this.getCustomIcons()?.entrypoint_widget_icon_inline_svg??void 0}getEmptyChatStateIconInlineSvg(){return this.getCustomIcons()?.empty_chat_state_icon_inline_svg??void 0}getEntrypointWidgetIconSize(){return this.loadConfig()?.entrypointWidgetIconSize??18}getUIAlignment(){return this.loadConfig()?.uiAlignment??null}getUIAlignmentAnchorSelector(){return this.getUIAlignment()?.anchor_selector??null}getUIAlignmentSide(){return this.getUIAlignment()?.side??"right"}}class a{static CACHE_KEY="deway-sdk-cache";static DB_NAME="DewaySdk";static DB_VERSION=1;static STORE_NAME="sdk";async cacheSDK(e,t,n,i){try{const d=(await this.openIndexedDB()).transaction([a.STORE_NAME],"readwrite").objectStore(a.STORE_NAME);await new Promise((y,S)=>{const h=d.put({id:"latest",code:e,version:t,checksum:n,signature:i,timestamp:Date.now()});h.onsuccess=()=>y(h.result),h.onerror=()=>S(h.error)})}catch{try{const s=JSON.stringify({code:e,version:t,checksum:n,signature:i,timestamp:Date.now()});localStorage.setItem(a.CACHE_KEY,s)}catch{}}}async getCachedSDK(){try{const n=(await this.openIndexedDB()).transaction([a.STORE_NAME],"readonly").objectStore(a.STORE_NAME),i=await new Promise((r,s)=>{const d=n.get("latest");d.onsuccess=()=>r(d.result||null),d.onerror=()=>s(d.error)});if(i)return i}catch{}try{const e=localStorage.getItem(a.CACHE_KEY);if(e)return JSON.parse(e)}catch{}return null}openIndexedDB(){return new Promise((e,t)=>{const n=indexedDB.open(a.DB_NAME,a.DB_VERSION);n.onerror=()=>t(n.error),n.onsuccess=()=>e(n.result),n.onupgradeneeded=i=>{const r=i.target.result;r.objectStoreNames.contains(a.STORE_NAME)||r.createObjectStore(a.STORE_NAME,{keyPath:"id"})}})}}async function E(o){const t=new TextEncoder().encode(o),n=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(n)).map(r=>r.toString(16).padStart(2,"0")).join("")}function w(o){const e=atob(o),t=new Uint8Array(e.length);for(let n=0;n<e.length;n++)t[n]=e.charCodeAt(n);return t}function D(o){const e=new Uint8Array(o.length/2);for(let t=0;t<o.length;t+=2)e[t/2]=Number.parseInt(o.substr(t,2),16);return e}async function A(o,e,t){try{const n=w(o),i=D(e),r=w(t),s=await crypto.subtle.importKey("raw",n,{name:"Ed25519"},!1,["verify"]);return await crypto.subtle.verify("Ed25519",s,r,i)}catch{return!1}}async function v(o,e,t,n){if(!e||!t)throw new Error("SDK verification failed: Missing security headers");if(await E(o)!==e)throw new Error("SDK verification failed: Checksum mismatch - content tampered");if(!await A(n,e,t))throw new Error("SDK verification failed: Invalid signature - content tampered")}class I{cleanApiEndpoint(e){return e.trim().replace(/\/+$/,"")}async fetchSDK(e,t,n){try{const i=this.cleanApiEndpoint(t),r=await fetch(`${i}/sdk-serve/sdk/v0`,{method:"GET",headers:{Accept:"application/javascript","deway-app-key":e,Origin:window?.location?.origin||""}});return r.ok?this.handleSuccessfulFetch(r,n):null}catch{return null}}async handleSuccessfulFetch(e,t){const n=e.headers.get("x-sdk-checksum"),i=e.headers.get("x-sdk-version"),r=e.headers.get("x-sdk-signature"),s=await e.text();if(!i||!s||!n)throw Object.fromEntries(e.headers.entries()),new Error("Invalid SDK response: missing version, code, or checksum");return await v(s,n,r,t),{code:s,version:i,checksum:n,signature:r||""}}}class g{static MAX_QUEUE_SIZE=50;commandQueue=[];queueCommand(e,...t){this.commandQueue.length>=g.MAX_QUEUE_SIZE&&this.commandQueue.shift(),this.commandQueue.push({method:e,args:t})}replayQueuedCommands(){if(this.commandQueue.length===0)return;const e=[...this.commandQueue];if(this.commandQueue=[],!!this.isSDKAvailable())for(const t of e)this.replayCommand(t)}clearQueue(){this.commandQueue=[]}isSDKAvailable(){return typeof window<"u"&&"Deway"in window&&!!window.Deway}replayCommand(e){try{const t=window.Deway,n=t?.[e.method];typeof n=="function"&&n.apply(t,e.args)}catch{}}}class f{static CACHE_KEY="deway-remote-config-cache";async cacheRemoteConfig(e,t){try{const n={config:e,ttl_seconds:t,timestamp:Date.now()};localStorage.setItem(f.CACHE_KEY,JSON.stringify(n))}catch{}}async getCachedRemoteConfig(){try{const e=localStorage.getItem(f.CACHE_KEY);return e?JSON.parse(e):null}catch{return null}}isCacheValid(e,t){const n=Date.now(),i=e+t*1e3;return n<i}}class b{cleanApiEndpoint(e){return e.trim().replace(/\/+$/,"")}async fetchRemoteConfig(e,t){try{const n=this.cleanApiEndpoint(t),i=await fetch(`${n}/sdk-remote-config-serve/`,{method:"GET",headers:{Accept:"application/json","deway-app-key":e,Origin:window?.location?.origin||""}});return i.ok?await i.json():null}catch{return null}}}class K{async executeSDK(e){return new Promise(t=>{try{if(!this.isDocumentReady()){t(!1);return}const n=document.createElement("script");n.textContent=e,n.type="text/javascript";let i=!1;const r=s=>{i||(i=!0,this.cleanupScript(n),t(s))};n.onerror=()=>{r(!1)},n.onload=()=>r(!0),document.head.appendChild(n),setTimeout(()=>{!i&&this.verifySDKLoaded()?r(!0):i||r(!1)},100)}catch{t(!1)}})}isDocumentReady(){return typeof document<"u"&&document.head!=null}verifySDKLoaded(){return typeof window<"u"&&"Deway"in window&&!!window.Deway}cleanupScript(e){try{e.parentNode&&e.parentNode.removeChild(e)}catch{}}}class k{validateConfig(e){return!(!e||!e.appKey||e.appKey.trim().length===0||e.apiEndpoint!==void 0&&!this.isValidUrl(e.apiEndpoint)||e.publicKey!==void 0&&e.publicKey.trim().length===0)}isValidUrl(e){try{return new URL(e),!0}catch{return!1}}}const m={apiEndpoint:"https://service.deway.app",publicKey:"9d3dBUvqyUQ7egd5j5uORdHSqZ7VFWOu+ud/SWt9WUY="};class _{isLoaded=!1;isLoading=!1;cacheManager;scriptExecutor;commandQueue;sdkFetcher;configValidator;remoteConfigFetcher;remoteConfigCache;sdkConfigStore;constructor(){this.cacheManager=new a,this.scriptExecutor=new K,this.commandQueue=new g,this.sdkFetcher=new I,this.configValidator=new k,this.sdkConfigStore=new C,this.remoteConfigFetcher=new b,this.remoteConfigCache=new f}init(e){this.performInit(e).catch(t=>{})}async performInit(e){try{if(!this.canInitialize())return;const t=this.isInitializationPayload(e),n=t?e.localConfig:e;if(!this.configValidator.validateConfig(n))return;this.isLoading=!0;const i=n.apiEndpoint||m.apiEndpoint,r=n.publicKey||m.publicKey,[s,d]=await Promise.all([this.fetchOrLoadSDK(n.appKey,i,r),this.fetchRemoteConfigWithCache(n,i)]);if(!s)return;const y=t?e:this.createInitializationPayload(d,n);if(!await this.scriptExecutor.executeSDK(s.code)||!this.initializeSDK(y))return;this.commandQueue.replayQueuedCommands(),this.isLoaded=!0}finally{this.isLoading=!1}}isInitializationPayload(e){return"localConfig"in e&&"remoteConfig"in e&&"defaults"in e}canInitialize(){return!(this.isLoaded||this.isLoading)}async fetchRemoteConfigWithCache(e,t){this.sdkConfigStore.saveConfig(e);const n=await this.remoteConfigFetcher.fetchRemoteConfig(e.appKey,t);if(n)return await this.remoteConfigCache.cacheRemoteConfig(n.config,n.ttl_seconds),n;const i=await this.remoteConfigCache.getCachedRemoteConfig();return i?{config:i.config,ttl_seconds:i.ttl_seconds}:null}createInitializationPayload(e,t){return{localConfig:t,remoteConfig:e?.config??null,defaults:m}}async fetchOrLoadSDK(e,t,n){const i=await this.sdkFetcher.fetchSDK(e,t,n);return i?(await this.cacheManager.cacheSDK(i.code,i.version,i.checksum,i.signature),i):this.loadFromCache()}async loadFromCache(){const e=await this.cacheManager.getCachedSDK();return e?{code:e.code,version:e.version}:null}initializeSDK(e){if(!this.isSDKAvailable())return!1;try{return window.Deway?.init(e),!0}catch{return!1}}identify(e){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.identify(e):this.commandQueue.queueCommand("identify",e)}catch{}}reportEvent(e,t){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.reportEvent(e,t):this.commandQueue.queueCommand("reportEvent",e,t)}catch{}}setUserProfile(e){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.setUserProfile(e):this.commandQueue.queueCommand("setUserProfile",e)}catch{}}show(e){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.show(e):this.commandQueue.queueCommand("show",e)}catch{}}hide(){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.hide():this.commandQueue.queueCommand("hide")}catch{}}openChat(){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.openChat():this.commandQueue.queueCommand("openChat")}catch{}}resetUserLocally(){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.resetUserLocally():this.commandQueue.queueCommand("resetUserLocally")}catch{}}isVisible(){try{return this.isLoaded&&this.isSDKAvailable()?window.Deway?.isVisible()??!1:!1}catch{return!1}}isInitialized(){try{return this.isLoaded&&this.isSDKAvailable()?window.Deway?.isInitialized()??!1:!1}catch{return!1}}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 _,p={init:o=>c.init(o),identify:o=>c.identify(o),reportEvent:(o,e)=>c.reportEvent(o,e),setUserProfile:o=>c.setUserProfile(o),show:o=>c.show(o),hide:()=>c.hide(),openChat:()=>c.openChat(),resetUserLocally:()=>c.resetUserLocally(),isVisible:()=>c.isVisible(),isInitialized:()=>c.isInitialized(),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}getSupportHandoff(){return this.loadConfig()?.supportHandoff??null}getSupportHandoffButtonText(){return this.getSupportHandoff()?.button_text??"talk to Support"}getFeatureFlags(){return this.loadConfig()?.featureFlags??{}}getFeatureFlag(e){return this.getFeatureFlags()[e]??!1}getPromptSuggestions(){return this.loadConfig()?.promptSuggestions}getWelcomeTitle(){return this.loadConfig()?.welcomeTitle??"How can I help you today?"}getWelcomeSubtitle(){return this.loadConfig()?.welcomeSubtitle??"I'm ready to help you navigate, learn, and get things done."}getEntrypointWidgetAppearanceMode(){return this.loadConfig()?.entrypointWidgetAppearanceMode??"bookmark"}getTenantTheme(){return this.loadConfig()?.tenantTheme??null}getTenantThemeForMode(e){const t=this.getTenantTheme();return t?e==="dark"?t.dark:t.light:null}getCustomIcons(){return this.loadConfig()?.customIcons??null}getEntrypointWidgetIconInlineSvg(){return this.getCustomIcons()?.entrypoint_widget_icon_inline_svg??void 0}getEmptyChatStateIconInlineSvg(){return this.getCustomIcons()?.empty_chat_state_icon_inline_svg??void 0}getEntrypointWidgetIconSize(){return this.loadConfig()?.entrypointWidgetIconSize??18}getUIAlignment(){return this.loadConfig()?.uiAlignment??null}getUIAlignmentAnchorSelector(){return this.getUIAlignment()?.anchor_selector??null}getUIAlignmentSide(){return this.getUIAlignment()?.side??"right"}}class c{static CACHE_KEY="deway-sdk-cache";static DB_NAME="DewaySdk";static DB_VERSION=1;static STORE_NAME="sdk";async cacheSDK(e,t,n,i){try{const d=(await this.openIndexedDB()).transaction([c.STORE_NAME],"readwrite").objectStore(c.STORE_NAME);await new Promise((y,S)=>{const h=d.put({id:"latest",code:e,version:t,checksum:n,signature:i,timestamp:Date.now()});h.onsuccess=()=>y(h.result),h.onerror=()=>S(h.error)})}catch{try{const a=JSON.stringify({code:e,version:t,checksum:n,signature:i,timestamp:Date.now()});localStorage.setItem(c.CACHE_KEY,a)}catch{}}}async getCachedSDK(){try{const n=(await this.openIndexedDB()).transaction([c.STORE_NAME],"readonly").objectStore(c.STORE_NAME),i=await new Promise((r,a)=>{const d=n.get("latest");d.onsuccess=()=>r(d.result||null),d.onerror=()=>a(d.error)});if(i)return i}catch{}try{const e=localStorage.getItem(c.CACHE_KEY);if(e)return JSON.parse(e)}catch{}return null}openIndexedDB(){return new Promise((e,t)=>{const n=indexedDB.open(c.DB_NAME,c.DB_VERSION);n.onerror=()=>t(n.error),n.onsuccess=()=>e(n.result),n.onupgradeneeded=i=>{const r=i.target.result;r.objectStoreNames.contains(c.STORE_NAME)||r.createObjectStore(c.STORE_NAME,{keyPath:"id"})}})}}async function E(o){const t=new TextEncoder().encode(o),n=await crypto.subtle.digest("SHA-256",t);return Array.from(new Uint8Array(n)).map(r=>r.toString(16).padStart(2,"0")).join("")}function p(o){const e=atob(o),t=new Uint8Array(e.length);for(let n=0;n<e.length;n++)t[n]=e.charCodeAt(n);return t}function D(o){const e=new Uint8Array(o.length/2);for(let t=0;t<o.length;t+=2)e[t/2]=Number.parseInt(o.substr(t,2),16);return e}async function A(o,e,t){try{const n=p(o),i=D(e),r=p(t),a=await crypto.subtle.importKey("raw",n,{name:"Ed25519"},!1,["verify"]);return await crypto.subtle.verify("Ed25519",a,r,i)}catch{return!1}}async function b(o,e,t,n){if(!e||!t)throw new Error("SDK verification failed: Missing security headers");if(await E(o)!==e)throw new Error("SDK verification failed: Checksum mismatch - content tampered");if(!await A(n,e,t))throw new Error("SDK verification failed: Invalid signature - content tampered")}class v{cleanApiEndpoint(e){return e.trim().replace(/\/+$/,"")}async fetchSDK(e,t,n){try{const i=this.cleanApiEndpoint(t),r=await fetch(`${i}/sdk-serve/sdk/v0`,{method:"GET",headers:{Accept:"application/javascript","deway-app-key":e,Origin:window?.location?.origin||""}});return r.ok?this.handleSuccessfulFetch(r,n):null}catch{return null}}async handleSuccessfulFetch(e,t){const n=e.headers.get("x-sdk-checksum"),i=e.headers.get("x-sdk-version"),r=e.headers.get("x-sdk-signature"),a=await e.text();if(!i||!a||!n)throw Object.fromEntries(e.headers.entries()),new Error("Invalid SDK response: missing version, code, or checksum");return await b(a,n,r,t),{code:a,version:i,checksum:n,signature:r||""}}}class g{static MAX_QUEUE_SIZE=50;commandQueue=[];queueCommand(e,...t){this.commandQueue.length>=g.MAX_QUEUE_SIZE&&this.commandQueue.shift(),this.commandQueue.push({method:e,args:t})}replayQueuedCommands(){if(this.commandQueue.length===0)return;const e=[...this.commandQueue];if(this.commandQueue=[],!!this.isSDKAvailable())for(const t of e)this.replayCommand(t)}clearQueue(){this.commandQueue=[]}isSDKAvailable(){return typeof window<"u"&&"Deway"in window&&!!window.Deway}replayCommand(e){try{const t=window.Deway,n=t?.[e.method];typeof n=="function"&&n.apply(t,e.args)}catch{}}}class f{static CACHE_KEY="deway-remote-config-cache";async cacheRemoteConfig(e,t){try{const n={config:e,ttl_seconds:t,timestamp:Date.now()};localStorage.setItem(f.CACHE_KEY,JSON.stringify(n))}catch{}}async getCachedRemoteConfig(){try{const e=localStorage.getItem(f.CACHE_KEY);return e?JSON.parse(e):null}catch{return null}}isCacheValid(e,t){const n=Date.now(),i=e+t*1e3;return n<i}}class I{cleanApiEndpoint(e){return e.trim().replace(/\/+$/,"")}async fetchRemoteConfig(e,t){try{const n=this.cleanApiEndpoint(t),i=await fetch(`${n}/sdk-remote-config-serve/`,{method:"GET",headers:{Accept:"application/json","deway-app-key":e,Origin:window?.location?.origin||""}});return i.ok?await i.json():null}catch{return null}}}class K{async executeSDK(e){return new Promise(t=>{try{if(!this.isDocumentReady()){t(!1);return}const n=document.createElement("script");n.textContent=e,n.type="text/javascript";let i=!1;const r=a=>{i||(i=!0,this.cleanupScript(n),t(a))};n.onerror=()=>{r(!1)},n.onload=()=>r(!0),document.head.appendChild(n),setTimeout(()=>{!i&&this.verifySDKLoaded()?r(!0):i||r(!1)},100)}catch{t(!1)}})}isDocumentReady(){return typeof document<"u"&&document.head!=null}verifySDKLoaded(){return typeof window<"u"&&"Deway"in window&&!!window.Deway}cleanupScript(e){try{e.parentNode&&e.parentNode.removeChild(e)}catch{}}}class k{validateConfig(e){return!(!e||!e.appKey||e.appKey.trim().length===0||e.apiEndpoint!==void 0&&!this.isValidUrl(e.apiEndpoint)||e.publicKey!==void 0&&e.publicKey.trim().length===0)}isValidUrl(e){try{return new URL(e),!0}catch{return!1}}}const m={apiEndpoint:"https://service.deway.app",publicKey:"9d3dBUvqyUQ7egd5j5uORdHSqZ7VFWOu+ud/SWt9WUY="};class _{isLoaded=!1;isLoading=!1;cacheManager;scriptExecutor;commandQueue;sdkFetcher;configValidator;remoteConfigFetcher;remoteConfigCache;sdkConfigStore;constructor(){this.cacheManager=new c,this.scriptExecutor=new K,this.commandQueue=new g,this.sdkFetcher=new v,this.configValidator=new k,this.sdkConfigStore=new C,this.remoteConfigFetcher=new I,this.remoteConfigCache=new f}init(e){this.performInit(e).catch(t=>{})}async performInit(e){try{if(!this.canInitialize())return;const t=this.isInitializationPayload(e),n=t?e.localConfig:e;if(!this.configValidator.validateConfig(n))return;this.isLoading=!0;const i=n.apiEndpoint||m.apiEndpoint,r=n.publicKey||m.publicKey,[a,d]=await Promise.all([this.fetchOrLoadSDK(n.appKey,i,r),this.fetchRemoteConfigWithCache(n,i)]);if(!a)return;const y=t?e:this.createInitializationPayload(d,n);if(!await this.scriptExecutor.executeSDK(a.code)||!this.initializeSDK(y))return;this.commandQueue.replayQueuedCommands(),this.isLoaded=!0}finally{this.isLoading=!1}}isInitializationPayload(e){return"localConfig"in e&&"remoteConfig"in e&&"defaults"in e}canInitialize(){return!(this.isLoaded||this.isLoading)}async fetchRemoteConfigWithCache(e,t){this.sdkConfigStore.saveConfig(e);const n=await this.remoteConfigFetcher.fetchRemoteConfig(e.appKey,t);if(n)return await this.remoteConfigCache.cacheRemoteConfig(n.config,n.ttl_seconds),n;const i=await this.remoteConfigCache.getCachedRemoteConfig();return i?{config:i.config,ttl_seconds:i.ttl_seconds}:null}createInitializationPayload(e,t){return{localConfig:t,remoteConfig:e?.config??null,defaults:m}}async fetchOrLoadSDK(e,t,n){const i=await this.sdkFetcher.fetchSDK(e,t,n);return i?(await this.cacheManager.cacheSDK(i.code,i.version,i.checksum,i.signature),i):this.loadFromCache()}async loadFromCache(){const e=await this.cacheManager.getCachedSDK();return e?{code:e.code,version:e.version}:null}initializeSDK(e){if(!this.isSDKAvailable())return!1;try{return window.Deway?.init(e),!0}catch{return!1}}identify(e){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.identify(e):this.commandQueue.queueCommand("identify",e)}catch{}}reportEvent(e,t){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.reportEvent(e,t):this.commandQueue.queueCommand("reportEvent",e,t)}catch{}}setUserProfile(e){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.setUserProfile(e):this.commandQueue.queueCommand("setUserProfile",e)}catch{}}show(e){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.show(e):this.commandQueue.queueCommand("show",e)}catch{}}hide(){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.hide():this.commandQueue.queueCommand("hide")}catch{}}openChat(){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.openChat():this.commandQueue.queueCommand("openChat")}catch{}}resetUserLocally(){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.resetUserLocally():this.commandQueue.queueCommand("resetUserLocally")}catch{}}isVisible(){try{return this.isLoaded&&this.isSDKAvailable()?window.Deway?.isVisible()??!1:!1}catch{return!1}}isInitialized(){try{return this.isLoaded&&this.isSDKAvailable()?window.Deway?.isInitialized()??!1:!1}catch{return!1}}registerSupportCallback(e){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.registerSupportCallback(e):this.commandQueue.queueCommand("registerSupportCallback",e)}catch{}}unregisterSupportCallback(){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.unregisterSupportCallback():this.commandQueue.queueCommand("unregisterSupportCallback")}catch{}}destroy(){try{this.isLoaded&&this.isSDKAvailable()?window.Deway?.destroy():this.commandQueue.queueCommand("destroy"),this.commandQueue.clearQueue()}catch{}}isSDKAvailable(){return typeof window<"u"&&"Deway"in window&&!!window.Deway}}const s=new _,w={init:o=>s.init(o),identify:o=>s.identify(o),reportEvent:(o,e)=>s.reportEvent(o,e),setUserProfile:o=>s.setUserProfile(o),show:o=>s.show(o),hide:()=>s.hide(),openChat:()=>s.openChat(),resetUserLocally:()=>s.resetUserLocally(),registerSupportCallback:o=>s.registerSupportCallback(o),unregisterSupportCallback:()=>s.unregisterSupportCallback(),isVisible:()=>s.isVisible(),isInitialized:()=>s.isInitialized(),destroy:()=>s.destroy()};return typeof window<"u"&&(window.Deway=w),w}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deway-ai/web-sdk",
3
- "version": "0.66.0",
3
+ "version": "0.68.0",
4
4
  "type": "module",
5
5
  "description": "Deway's Web SDK",
6
6
  "main": "dist/loader.umd.js",