@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 +9 -9
- package/dist/loader.d.ts +2 -2
- package/dist/loader.es.js +66 -57
- package/dist/loader.umd.js +1 -1
- package/package.json +1 -1
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
|
-
|
|
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
|
-
|
|
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.
|
|
180
|
+
### `Deway.showBookmark(config?)`
|
|
181
181
|
|
|
182
|
-
Show the AI chat
|
|
182
|
+
Show the AI chat bookmark. Optional configuration for appearance customization.
|
|
183
183
|
|
|
184
|
-
### `Deway.
|
|
184
|
+
### `Deway.hideBookmark()`
|
|
185
185
|
|
|
186
|
-
Hide the AI chat
|
|
186
|
+
Hide the AI chat bookmark.
|
|
187
187
|
|
|
188
|
-
### `Deway.
|
|
188
|
+
### `Deway.isBookmarkVisible()`
|
|
189
189
|
|
|
190
|
-
Check if the
|
|
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 `
|
|
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 {
|
|
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 {
|
|
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
|
|
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(
|
|
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(
|
|
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
|
|
57
|
-
await new Promise((f,
|
|
58
|
-
const l =
|
|
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 = () =>
|
|
69
|
+
l.onsuccess = () => f(l.result), l.onerror = () => m(l.error);
|
|
67
70
|
});
|
|
68
71
|
} catch {
|
|
69
72
|
try {
|
|
70
|
-
const
|
|
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,
|
|
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((
|
|
85
|
-
const
|
|
86
|
-
|
|
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
|
|
105
|
-
|
|
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((
|
|
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
|
|
129
|
+
async function D(r, e, t) {
|
|
127
130
|
try {
|
|
128
|
-
const i = w(r), n = E(e),
|
|
129
|
-
return await crypto.subtle.verify("Ed25519",
|
|
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
|
|
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
|
|
142
|
+
if (!await D(i, e, t))
|
|
140
143
|
throw new Error("SDK verification failed: Invalid signature - content tampered");
|
|
141
144
|
}
|
|
142
|
-
class
|
|
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),
|
|
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
|
|
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"),
|
|
163
|
-
if (!n || !
|
|
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
|
|
168
|
+
return await A(o, i, a, t), { code: o, version: n, checksum: i, signature: a || "" };
|
|
166
169
|
}
|
|
167
170
|
}
|
|
168
|
-
class
|
|
171
|
+
class g {
|
|
169
172
|
static MAX_QUEUE_SIZE = 50;
|
|
170
173
|
commandQueue = [];
|
|
171
174
|
queueCommand(e, ...t) {
|
|
172
|
-
this.commandQueue.length >=
|
|
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
|
|
283
|
-
n || (n = !0, this.cleanupScript(i), t(
|
|
285
|
+
const a = (o) => {
|
|
286
|
+
n || (n = !0, this.cleanupScript(i), t(o));
|
|
284
287
|
};
|
|
285
288
|
i.onerror = () => {
|
|
286
|
-
|
|
287
|
-
}, i.onload = () =>
|
|
288
|
-
!n && this.verifySDKLoaded() ?
|
|
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
|
|
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
|
|
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,
|
|
353
|
-
if (!
|
|
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(
|
|
356
|
-
if (!await this.scriptExecutor.executeSDK(
|
|
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
|
-
|
|
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?.
|
|
440
|
+
this.isLoaded && this.isSDKAvailable() ? window.Deway?.hide() : this.commandQueue.queueCommand("hide");
|
|
434
441
|
} catch {
|
|
435
442
|
}
|
|
436
443
|
}
|
|
437
|
-
|
|
444
|
+
isVisible() {
|
|
438
445
|
try {
|
|
439
|
-
this.isLoaded && this.isSDKAvailable() ? window.Deway?.
|
|
446
|
+
return this.isLoaded && this.isSDKAvailable() ? window.Deway?.isVisible() ?? !1 : !1;
|
|
440
447
|
} catch {
|
|
448
|
+
return !1;
|
|
441
449
|
}
|
|
442
450
|
}
|
|
443
|
-
|
|
451
|
+
isInitialized() {
|
|
444
452
|
try {
|
|
445
|
-
return this.isLoaded && this.isSDKAvailable() ? window.Deway?.
|
|
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
|
|
461
|
-
init: (r) =>
|
|
462
|
-
identify: (r) =>
|
|
463
|
-
reportEvent: (r, e) =>
|
|
464
|
-
setUserProfile: (r) =>
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
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 {
|
package/dist/loader.umd.js
CHANGED
|
@@ -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
|
|
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}));
|