@clonus/js-client 2.0.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/LICENSE +21 -0
- package/dist/client/autocapture.d.ts +13 -0
- package/dist/client/autocapture.d.ts.map +1 -0
- package/dist/client/client.d.ts +55 -0
- package/dist/client/client.d.ts.map +1 -0
- package/dist/client/device.d.ts +11 -0
- package/dist/client/device.d.ts.map +1 -0
- package/dist/client/event.d.ts +14 -0
- package/dist/client/event.d.ts.map +1 -0
- package/dist/client/identity.d.ts +7 -0
- package/dist/client/identity.d.ts.map +1 -0
- package/dist/client/network.d.ts +13 -0
- package/dist/client/network.d.ts.map +1 -0
- package/dist/client/options.d.ts +36 -0
- package/dist/client/options.d.ts.map +1 -0
- package/dist/client/session.d.ts +14 -0
- package/dist/client/session.d.ts.map +1 -0
- package/dist/client/storage.d.ts +19 -0
- package/dist/client/storage.d.ts.map +1 -0
- package/dist/client/user.d.ts +16 -0
- package/dist/client/user.d.ts.map +1 -0
- package/dist/clonus.umd.js +3 -0
- package/dist/clonus.umd.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +804 -0
- package/dist/index.mjs.map +1 -0
- package/dist/utils/element.d.ts +12 -0
- package/dist/utils/element.d.ts.map +1 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/logging/errors.d.ts +7 -0
- package/dist/utils/logging/errors.d.ts.map +1 -0
- package/dist/utils/logging/logger.d.ts +8 -0
- package/dist/utils/logging/logger.d.ts.map +1 -0
- package/dist/utils/storage/cookie.d.ts +7 -0
- package/dist/utils/storage/cookie.d.ts.map +1 -0
- package/dist/utils/storage/local.d.ts +7 -0
- package/dist/utils/storage/local.d.ts.map +1 -0
- package/dist/utils/user_agent.d.ts +18 -0
- package/dist/utils/user_agent.d.ts.map +1 -0
- package/package.json +37 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,804 @@
|
|
|
1
|
+
const f = "https://api.clonus.io/v1";
|
|
2
|
+
class y {
|
|
3
|
+
constructor(e) {
|
|
4
|
+
const t = e ?? {};
|
|
5
|
+
this.apiUrl = f.endsWith("/") ? f : f + "/", this.autocapture = t.autocapture ?? !0, this.flushInterval = this.normalizeNumberInput(t.flush?.interval, {
|
|
6
|
+
default: 1e4,
|
|
7
|
+
min: 1e3,
|
|
8
|
+
max: 6e4
|
|
9
|
+
}), this.flushThreshold = this.normalizeNumberInput(t.flush?.threshold, {
|
|
10
|
+
default: 50,
|
|
11
|
+
min: 1,
|
|
12
|
+
max: 500
|
|
13
|
+
}), this.sessionDuration = this.normalizeNumberInput(t.session?.duration, {
|
|
14
|
+
default: 18e5,
|
|
15
|
+
min: 6e4,
|
|
16
|
+
max: 864e5
|
|
17
|
+
}), this.sessionStorageEnabled = t.session?.storage ?? !0, this.sdkVersion = t.$sdk?.version ?? "0.0.1", this.sdkLibrary = t.$sdk?.library ?? "js-client";
|
|
18
|
+
}
|
|
19
|
+
getApiUrl() {
|
|
20
|
+
return this.apiUrl;
|
|
21
|
+
}
|
|
22
|
+
getAutocapture() {
|
|
23
|
+
return this.autocapture;
|
|
24
|
+
}
|
|
25
|
+
getFlushInterval() {
|
|
26
|
+
return this.flushInterval;
|
|
27
|
+
}
|
|
28
|
+
getFlushThreshold() {
|
|
29
|
+
return this.flushThreshold;
|
|
30
|
+
}
|
|
31
|
+
getSessionDuration() {
|
|
32
|
+
return this.sessionDuration;
|
|
33
|
+
}
|
|
34
|
+
isSessionStorageEnabled() {
|
|
35
|
+
return this.sessionStorageEnabled;
|
|
36
|
+
}
|
|
37
|
+
getSDKVersion() {
|
|
38
|
+
return this.sdkVersion;
|
|
39
|
+
}
|
|
40
|
+
getSDKLibrary() {
|
|
41
|
+
return this.sdkLibrary;
|
|
42
|
+
}
|
|
43
|
+
normalizeNumberInput(e, t) {
|
|
44
|
+
return e == null || typeof e != "number" || isNaN(e) || !isFinite(e) ? t.default : Math.max(Math.min(e, t.max), t.min);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const k = 1e4, v = 3, b = 1e3, E = 30;
|
|
48
|
+
class A {
|
|
49
|
+
constructor(e = 30) {
|
|
50
|
+
this.leakyBucket = /* @__PURE__ */ new Map(), this.threshold = e;
|
|
51
|
+
}
|
|
52
|
+
shouldContinue(e) {
|
|
53
|
+
return this.getCount(e) < this.threshold;
|
|
54
|
+
}
|
|
55
|
+
acquire(e) {
|
|
56
|
+
this.leakyBucket.set(e, this.getCount(e) + 1);
|
|
57
|
+
}
|
|
58
|
+
release(e) {
|
|
59
|
+
const t = this.getCount(e);
|
|
60
|
+
t > 0 && this.leakyBucket.set(e, t - 1);
|
|
61
|
+
}
|
|
62
|
+
getCount(e) {
|
|
63
|
+
return this.leakyBucket.get(e) || 0;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
class U {
|
|
67
|
+
constructor(e, t) {
|
|
68
|
+
if (this.retryCodes = [408, 500, 502, 503, 504, 522, 524, 599], !e || typeof e != "string")
|
|
69
|
+
throw new Error("API key is required");
|
|
70
|
+
this.apiKey = e, this.baseUrl = t, this.rateLimiter = new A(E);
|
|
71
|
+
}
|
|
72
|
+
async post(e, t) {
|
|
73
|
+
const s = k, i = v, n = b, o = `${this.baseUrl}${e}`;
|
|
74
|
+
if (!this.rateLimiter.shouldContinue(e))
|
|
75
|
+
throw new Error("Rate limit exceeded");
|
|
76
|
+
this.rateLimiter.acquire(e);
|
|
77
|
+
try {
|
|
78
|
+
return await this.fetchWithRetry(o, t, i, n, s);
|
|
79
|
+
} finally {
|
|
80
|
+
this.rateLimiter.release(e);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async fetchWithRetry(e, t, s, i, n, o = 1) {
|
|
84
|
+
const l = new AbortController(), u = setTimeout(() => l.abort(), n);
|
|
85
|
+
try {
|
|
86
|
+
const a = await fetch(e, {
|
|
87
|
+
method: "POST",
|
|
88
|
+
headers: {
|
|
89
|
+
"Content-Type": "application/json",
|
|
90
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
91
|
+
},
|
|
92
|
+
body: JSON.stringify(t),
|
|
93
|
+
signal: l.signal,
|
|
94
|
+
keepalive: !0
|
|
95
|
+
});
|
|
96
|
+
if (!a.ok && this.shouldRetryStatus(a.status) && o < s)
|
|
97
|
+
return await this.waitBeforeRetry(i), this.fetchWithRetry(e, t, s, i * 2, n, o + 1);
|
|
98
|
+
if (!a.ok)
|
|
99
|
+
throw new Error(`HTTP ${a.status}: ${a.statusText}`);
|
|
100
|
+
return a.json();
|
|
101
|
+
} catch (a) {
|
|
102
|
+
if (o < s && this.shouldRetryError(a))
|
|
103
|
+
return await this.waitBeforeRetry(i), this.fetchWithRetry(e, t, s, i * 2, n, o + 1);
|
|
104
|
+
throw a instanceof Error && a.name === "AbortError" ? new Error(`Request timeout after ${n}ms`) : a;
|
|
105
|
+
} finally {
|
|
106
|
+
clearTimeout(u);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
shouldRetryStatus(e) {
|
|
110
|
+
return this.retryCodes.includes(e);
|
|
111
|
+
}
|
|
112
|
+
shouldRetryError(e) {
|
|
113
|
+
return e instanceof Error ? e.name === "AbortError" || e.message.includes("network") : !1;
|
|
114
|
+
}
|
|
115
|
+
waitBeforeRetry(e) {
|
|
116
|
+
return new Promise((t) => setTimeout(t, e));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
class _ {
|
|
120
|
+
constructor(e, t) {
|
|
121
|
+
this.localStorage = e, this.cookieStorage = t;
|
|
122
|
+
}
|
|
123
|
+
getPersistent(e) {
|
|
124
|
+
return this.localStorage.getItem(e);
|
|
125
|
+
}
|
|
126
|
+
setPersistent(e, t) {
|
|
127
|
+
this.localStorage.setItem(e, t);
|
|
128
|
+
}
|
|
129
|
+
removePersistent(e) {
|
|
130
|
+
this.localStorage.removeItem(e);
|
|
131
|
+
}
|
|
132
|
+
getCookie(e) {
|
|
133
|
+
return this.cookieStorage.getItem(e);
|
|
134
|
+
}
|
|
135
|
+
setCookie(e, t) {
|
|
136
|
+
this.cookieStorage.setItem(e, t);
|
|
137
|
+
}
|
|
138
|
+
removeCookie(e) {
|
|
139
|
+
this.cookieStorage.removeItem(e);
|
|
140
|
+
}
|
|
141
|
+
getJSON(e) {
|
|
142
|
+
const t = this.getPersistent(e);
|
|
143
|
+
if (!t) return null;
|
|
144
|
+
try {
|
|
145
|
+
return JSON.parse(t);
|
|
146
|
+
} catch {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
setJSON(e, t) {
|
|
151
|
+
this.setPersistent(e, JSON.stringify(t));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
class C {
|
|
155
|
+
getItem(e) {
|
|
156
|
+
try {
|
|
157
|
+
return typeof window > "u" || !window.localStorage ? null : window.localStorage.getItem(e);
|
|
158
|
+
} catch {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
setItem(e, t) {
|
|
163
|
+
try {
|
|
164
|
+
if (typeof window > "u" || !window.localStorage)
|
|
165
|
+
return;
|
|
166
|
+
window.localStorage.setItem(e, t);
|
|
167
|
+
} catch {
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
removeItem(e) {
|
|
171
|
+
try {
|
|
172
|
+
if (typeof window > "u" || !window.localStorage)
|
|
173
|
+
return;
|
|
174
|
+
window.localStorage.removeItem(e);
|
|
175
|
+
} catch {
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
class L {
|
|
180
|
+
getItem(e) {
|
|
181
|
+
try {
|
|
182
|
+
if (typeof document > "u")
|
|
183
|
+
return null;
|
|
184
|
+
const t = e + "=", i = decodeURIComponent(document.cookie).split(";");
|
|
185
|
+
for (let n = 0; n < i.length; n++) {
|
|
186
|
+
let o = i[n];
|
|
187
|
+
for (; o.charAt(0) === " "; )
|
|
188
|
+
o = o.substring(1);
|
|
189
|
+
if (o.indexOf(t) === 0)
|
|
190
|
+
return o.substring(t.length, o.length);
|
|
191
|
+
}
|
|
192
|
+
return null;
|
|
193
|
+
} catch {
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
setItem(e, t) {
|
|
198
|
+
try {
|
|
199
|
+
if (typeof document > "u")
|
|
200
|
+
return;
|
|
201
|
+
const s = /* @__PURE__ */ new Date();
|
|
202
|
+
s.setFullYear(s.getFullYear() + 1), document.cookie = `${e}=${t};expires=${s.toUTCString()};path=/`;
|
|
203
|
+
} catch {
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
removeItem(e) {
|
|
207
|
+
try {
|
|
208
|
+
if (typeof document > "u")
|
|
209
|
+
return;
|
|
210
|
+
document.cookie = `${e}=;expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/`;
|
|
211
|
+
} catch {
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
class g extends Error {
|
|
216
|
+
constructor(e) {
|
|
217
|
+
super(e ?? "Call and wait for initializeAsync() to finish first."), this.name = "ClonusUninitializedError", Object.setPrototypeOf(this, g.prototype);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
class h extends Error {
|
|
221
|
+
constructor(e) {
|
|
222
|
+
super(e), this.name = "ClonusInvalidArgumentError", Object.setPrototypeOf(this, h.prototype);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
class T {
|
|
226
|
+
constructor(e) {
|
|
227
|
+
if (!e || typeof e != "object")
|
|
228
|
+
throw new h("User object is required");
|
|
229
|
+
if (!e.email || typeof e.email != "string" || e.email.trim().length === 0)
|
|
230
|
+
throw new h("User email is required");
|
|
231
|
+
if (!e.id || typeof e.id != "string" || e.id.trim().length === 0)
|
|
232
|
+
throw new h("User id is required");
|
|
233
|
+
this.email = e.email.trim().toLowerCase(), this.id = e.id.trim(), this.properties = e.properties ?? {};
|
|
234
|
+
}
|
|
235
|
+
getEmail() {
|
|
236
|
+
return this.email;
|
|
237
|
+
}
|
|
238
|
+
getUserId() {
|
|
239
|
+
return this.id;
|
|
240
|
+
}
|
|
241
|
+
getProperties() {
|
|
242
|
+
return { ...this.properties };
|
|
243
|
+
}
|
|
244
|
+
toJSON() {
|
|
245
|
+
return {
|
|
246
|
+
id: this.id,
|
|
247
|
+
email: this.email,
|
|
248
|
+
properties: this.properties
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
class I {
|
|
253
|
+
constructor(e) {
|
|
254
|
+
this.sdk = e;
|
|
255
|
+
}
|
|
256
|
+
async initAsync() {
|
|
257
|
+
const e = this.sdk.getUser();
|
|
258
|
+
if (e.getEmail() || this.sdk.getBrowser())
|
|
259
|
+
return Promise.resolve();
|
|
260
|
+
try {
|
|
261
|
+
await this.sdk.getNetwork().post("/identify", {
|
|
262
|
+
user_id: e.getUserId(),
|
|
263
|
+
user_email: e.getEmail(),
|
|
264
|
+
user_properties: e.getProperties(),
|
|
265
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
266
|
+
});
|
|
267
|
+
} catch {
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
const c = [];
|
|
272
|
+
for (let r = 0; r < 256; ++r)
|
|
273
|
+
c.push((r + 256).toString(16).slice(1));
|
|
274
|
+
function O(r, e = 0) {
|
|
275
|
+
return (c[r[e + 0]] + c[r[e + 1]] + c[r[e + 2]] + c[r[e + 3]] + "-" + c[r[e + 4]] + c[r[e + 5]] + "-" + c[r[e + 6]] + c[r[e + 7]] + "-" + c[r[e + 8]] + c[r[e + 9]] + "-" + c[r[e + 10]] + c[r[e + 11]] + c[r[e + 12]] + c[r[e + 13]] + c[r[e + 14]] + c[r[e + 15]]).toLowerCase();
|
|
276
|
+
}
|
|
277
|
+
let m;
|
|
278
|
+
const x = new Uint8Array(16);
|
|
279
|
+
function D() {
|
|
280
|
+
if (!m) {
|
|
281
|
+
if (typeof crypto > "u" || !crypto.getRandomValues)
|
|
282
|
+
throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");
|
|
283
|
+
m = crypto.getRandomValues.bind(crypto);
|
|
284
|
+
}
|
|
285
|
+
return m(x);
|
|
286
|
+
}
|
|
287
|
+
const R = typeof crypto < "u" && crypto.randomUUID && crypto.randomUUID.bind(crypto), p = { randomUUID: R };
|
|
288
|
+
function P(r, e, t) {
|
|
289
|
+
r = r || {};
|
|
290
|
+
const s = r.random ?? r.rng?.() ?? D();
|
|
291
|
+
if (s.length < 16)
|
|
292
|
+
throw new Error("Random bytes length must be >= 16");
|
|
293
|
+
return s[6] = s[6] & 15 | 64, s[8] = s[8] & 63 | 128, O(s);
|
|
294
|
+
}
|
|
295
|
+
function S(r, e, t) {
|
|
296
|
+
return p.randomUUID && !r ? p.randomUUID() : P(r);
|
|
297
|
+
}
|
|
298
|
+
class $ {
|
|
299
|
+
constructor(e) {
|
|
300
|
+
this.currentSession = null, this.storageKey = "clonus_session", this.sdk = e;
|
|
301
|
+
}
|
|
302
|
+
getOrCreateSessionId() {
|
|
303
|
+
return (this.getActiveSession() || this.createSession()).sessionId;
|
|
304
|
+
}
|
|
305
|
+
getActiveSession() {
|
|
306
|
+
const e = this.currentSession || this.loadFromStorage();
|
|
307
|
+
if (!e) return null;
|
|
308
|
+
const t = this.sdk.getOptions().getSessionDuration();
|
|
309
|
+
return e.expiration > Date.now() ? this.extendSession(e, t) : null;
|
|
310
|
+
}
|
|
311
|
+
createSession() {
|
|
312
|
+
const e = (/* @__PURE__ */ new Date()).toISOString(), t = this.sdk.getOptions().getSessionDuration(), s = {
|
|
313
|
+
sessionId: S(),
|
|
314
|
+
startTime: e,
|
|
315
|
+
lastActivity: e,
|
|
316
|
+
expiration: Date.now() + t
|
|
317
|
+
};
|
|
318
|
+
return this.currentSession = s, this.persistToStorage(s), s;
|
|
319
|
+
}
|
|
320
|
+
extendSession(e, t) {
|
|
321
|
+
const s = {
|
|
322
|
+
...e,
|
|
323
|
+
lastActivity: (/* @__PURE__ */ new Date()).toISOString(),
|
|
324
|
+
expiration: Date.now() + t
|
|
325
|
+
};
|
|
326
|
+
return this.currentSession = s, this.persistToStorage(s), s;
|
|
327
|
+
}
|
|
328
|
+
loadFromStorage() {
|
|
329
|
+
const e = this.sdk.getStorage().getPersistent(this.storageKey);
|
|
330
|
+
if (!e) return null;
|
|
331
|
+
try {
|
|
332
|
+
const t = JSON.parse(e);
|
|
333
|
+
return Date.now() < t.expiration ? t : null;
|
|
334
|
+
} catch {
|
|
335
|
+
return null;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
persistToStorage(e) {
|
|
339
|
+
this.sdk.getOptions().isSessionStorageEnabled() && (this.sdk.getStorage().setPersistent(this.storageKey, JSON.stringify(e)), this.sdk.getStorage().setCookie(this.storageKey, e.sessionId));
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
class M {
|
|
343
|
+
constructor(e) {
|
|
344
|
+
this.storageKey = "clonus_device_id", this.sdk = e;
|
|
345
|
+
}
|
|
346
|
+
getOrCreateDeviceId() {
|
|
347
|
+
if (this.deviceId)
|
|
348
|
+
return this.deviceId;
|
|
349
|
+
const e = this.loadFromStorage();
|
|
350
|
+
if (e)
|
|
351
|
+
return this.deviceId = e, e;
|
|
352
|
+
const t = S();
|
|
353
|
+
return this.deviceId = t, this.persistToStorage(t), t;
|
|
354
|
+
}
|
|
355
|
+
loadFromStorage() {
|
|
356
|
+
return this.sdk.getStorage().getCookie(this.storageKey) || this.sdk.getStorage().getPersistent(this.storageKey);
|
|
357
|
+
}
|
|
358
|
+
persistToStorage(e) {
|
|
359
|
+
this.sdk.getStorage().setCookie(this.storageKey, e), this.sdk.getStorage().setPersistent(this.storageKey, e);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
class N {
|
|
363
|
+
parse(e) {
|
|
364
|
+
const t = this.browser(e), s = this.os(e), i = this.device(e);
|
|
365
|
+
return {
|
|
366
|
+
browser_name: t.name,
|
|
367
|
+
browser_version: t.version,
|
|
368
|
+
os_name: s.name,
|
|
369
|
+
os_version: s.version,
|
|
370
|
+
device_brand: i.brand,
|
|
371
|
+
device_model: i.model
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
browser(e) {
|
|
375
|
+
let t = "Unknown", s = "Unknown", i;
|
|
376
|
+
return e.includes("Firefox/") ? (t = "Firefox", i = e.match(/Firefox\/(\d+\.\d+)/), s = i ? i[1] : "Unknown") : e.includes("Edg/") ? (t = "Edge", i = e.match(/Edg\/(\d+\.\d+)/), s = i ? i[1] : "Unknown") : e.includes("Chrome/") ? (t = "Chrome", i = e.match(/Chrome\/(\d+\.\d+)/), s = i ? i[1] : "Unknown") : e.includes("Safari/") && !e.includes("Chrome") ? (t = "Safari", i = e.match(/Version\/(\d+\.\d+)/), s = i ? i[1] : "Unknown") : (e.includes("Opera/") || e.includes("OPR/")) && (t = "Opera", i = e.match(/OPR\/(\d+\.\d+)/), s = i ? i[1] : "Unknown"), { name: t, version: s };
|
|
377
|
+
}
|
|
378
|
+
os(e) {
|
|
379
|
+
let t = "Unknown", s = "Unknown", i;
|
|
380
|
+
if (e.includes("Windows NT")) {
|
|
381
|
+
if (t = "Windows", i = e.match(/Windows NT (\d+\.\d+)/), i) {
|
|
382
|
+
const n = i[1];
|
|
383
|
+
n === "10.0" ? s = "10" : n === "6.3" ? s = "8.1" : n === "6.2" ? s = "8" : n === "6.1" ? s = "7" : s = n;
|
|
384
|
+
}
|
|
385
|
+
} else e.includes("Mac OS X") ? (t = "Mac OS X", i = e.match(/Mac OS X (\d+[._]\d+[._]?\d*)/), s = i ? i[1].replace(/_/g, ".") : "Unknown") : e.includes("Android") ? (t = "Android", i = e.match(/Android (\d+\.\d+)/), s = i ? i[1] : "Unknown") : e.includes("iPhone") || e.includes("iPad") ? (t = "iOS", i = e.match(/OS (\d+_\d+)/), s = i ? i[1].replace(/_/g, ".") : "Unknown") : e.includes("Linux") && (t = "Linux");
|
|
386
|
+
return { name: t, version: s };
|
|
387
|
+
}
|
|
388
|
+
device(e) {
|
|
389
|
+
let t = "Unknown", s = "Unknown", i;
|
|
390
|
+
if (e.includes("iPhone"))
|
|
391
|
+
t = "Apple", s = "iPhone";
|
|
392
|
+
else if (e.includes("iPad"))
|
|
393
|
+
t = "Apple", s = "iPad";
|
|
394
|
+
else if (e.includes("Macintosh") || e.includes("Mac OS X"))
|
|
395
|
+
t = "Apple", s = "Mac";
|
|
396
|
+
else if (i = e.match(/Samsung|SM-[A-Z0-9]+|GT-[A-Z0-9]+/)) {
|
|
397
|
+
t = "Samsung";
|
|
398
|
+
const o = e.match(/SM-([A-Z0-9]+)|GT-([A-Z0-9]+)/);
|
|
399
|
+
s = o ? o[1] || o[2] : "Galaxy";
|
|
400
|
+
} else e.includes("Pixel") ? (t = "Google", i = e.match(/Pixel (\d+[a-zA-Z]*)/), s = i ? `Pixel ${i[1]}` : "Pixel") : e.includes("Huawei") || e.includes("HUAWEI") ? (t = "Huawei", i = e.match(/([A-Z]{3}-[A-Z0-9]+)/), s = i ? i[1] : "Huawei") : e.includes("Xiaomi") || e.includes("Mi ") || e.includes("Redmi") ? (t = "Xiaomi", i = e.match(/Mi ([A-Z0-9 ]+)|Redmi ([A-Z0-9 ]+)/), s = i && (i[1] || i[2]) || "Mi") : e.includes("OnePlus") || e.includes("ONEPLUS") ? (t = "OnePlus", i = e.match(/OnePlus ([A-Z0-9]+)/), s = i ? i[1] : "OnePlus") : e.includes("Windows") ? (t = "PC", s = "Windows") : e.includes("Linux") && !e.includes("Android") ? (t = "PC", s = "Linux") : e.includes("Android") && (t = "Android", s = "Android Device");
|
|
401
|
+
let n = "Desktop";
|
|
402
|
+
return /(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i.test(e) ? n = "Tablet" : /Mobile|Android|iP(hone|od)|IEMobile|BlackBerry|Kindle|Silk-Accelerated|(hpw|web)OS|Opera M(obi|ini)/.test(
|
|
403
|
+
e
|
|
404
|
+
) && (n = "Mobile"), { type: n, brand: t, model: s };
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
class F {
|
|
408
|
+
constructor(e) {
|
|
409
|
+
this.storage = e, this.queue = [], this.storageKey = "clonus_event_queue", this.MAX_QUEUE_SIZE = 1e3, this.loadFromStorage();
|
|
410
|
+
}
|
|
411
|
+
enqueue(e) {
|
|
412
|
+
this.queue.length >= this.MAX_QUEUE_SIZE && this.queue.shift(), this.queue.push(e), this.persistToStorage();
|
|
413
|
+
}
|
|
414
|
+
getAll() {
|
|
415
|
+
return [...this.queue];
|
|
416
|
+
}
|
|
417
|
+
clear() {
|
|
418
|
+
this.queue = [], this.persistToStorage();
|
|
419
|
+
}
|
|
420
|
+
size() {
|
|
421
|
+
return this.queue.length;
|
|
422
|
+
}
|
|
423
|
+
loadFromStorage() {
|
|
424
|
+
const e = this.storage.getJSON(this.storageKey);
|
|
425
|
+
this.queue = e ? e.slice(0, this.MAX_QUEUE_SIZE) : [];
|
|
426
|
+
}
|
|
427
|
+
persistToStorage() {
|
|
428
|
+
this.storage.setJSON(this.storageKey, this.queue);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
class q {
|
|
432
|
+
constructor(e) {
|
|
433
|
+
this.storage = e, this.failedRetries = [], this.storageKey = "clonus_failed_requests", this.MAX_FAILED_REQUESTS = 100, this.MAX_AGE_MS = 7200 * 60 * 1e3, this.MAX_ATTEMPTS = 5, this.loadFromStorage();
|
|
434
|
+
}
|
|
435
|
+
add(e, t) {
|
|
436
|
+
const s = {
|
|
437
|
+
endpoint: e,
|
|
438
|
+
body: t,
|
|
439
|
+
timestamp: Date.now(),
|
|
440
|
+
retryCount: 0
|
|
441
|
+
};
|
|
442
|
+
this.failedRetries.length >= this.MAX_FAILED_REQUESTS && this.failedRetries.shift(), this.failedRetries.push(s), this.persistToStorage();
|
|
443
|
+
}
|
|
444
|
+
getAll() {
|
|
445
|
+
if (this.failedRetries.length === 0) return [];
|
|
446
|
+
const e = Date.now();
|
|
447
|
+
return this.failedRetries.filter(
|
|
448
|
+
(t) => e - t.timestamp <= this.MAX_AGE_MS && t.retryCount < this.MAX_ATTEMPTS
|
|
449
|
+
);
|
|
450
|
+
}
|
|
451
|
+
clearAll() {
|
|
452
|
+
this.failedRetries = [], this.persistToStorage();
|
|
453
|
+
}
|
|
454
|
+
loadFromStorage() {
|
|
455
|
+
const e = this.storage.getJSON(this.storageKey);
|
|
456
|
+
this.failedRetries = e ? e.slice(0, this.MAX_FAILED_REQUESTS) : [];
|
|
457
|
+
}
|
|
458
|
+
persistToStorage() {
|
|
459
|
+
this.storage.setJSON(this.storageKey, this.failedRetries);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
class K {
|
|
463
|
+
constructor(e) {
|
|
464
|
+
this.sdk = e, this.queue = new F(this.sdk.getStorage()), this.retry = new q(this.sdk.getStorage()), this.ua = new N();
|
|
465
|
+
const t = this.sdk.getOptions().getFlushInterval();
|
|
466
|
+
this.flushTimer = setInterval(() => {
|
|
467
|
+
this.flush();
|
|
468
|
+
}, t);
|
|
469
|
+
}
|
|
470
|
+
enqueue(e, t, s) {
|
|
471
|
+
this.sdk.getLogger().swallow("enqueue", () => {
|
|
472
|
+
if (!this.sdk.getBrowser()) return;
|
|
473
|
+
const i = this.ua.parse(navigator.userAgent);
|
|
474
|
+
this.queue.enqueue({
|
|
475
|
+
user_id: this.sdk.getUser().getUserId(),
|
|
476
|
+
device_id: this.sdk.getDevice().getOrCreateDeviceId(),
|
|
477
|
+
session_id: this.sdk.getSession().getOrCreateSessionId(),
|
|
478
|
+
message: t,
|
|
479
|
+
level: e,
|
|
480
|
+
properties: {
|
|
481
|
+
$page_url: window.location.href,
|
|
482
|
+
$page_host: window.location.hostname,
|
|
483
|
+
$page_path: window.location.pathname,
|
|
484
|
+
$page_title: document.title,
|
|
485
|
+
$page_referrer: document.referrer,
|
|
486
|
+
$browser_name: i.browser_name,
|
|
487
|
+
$browser_version: i.browser_version,
|
|
488
|
+
$os_name: i.os_name,
|
|
489
|
+
$os_version: i.os_version,
|
|
490
|
+
$device_brand: i.device_brand,
|
|
491
|
+
$device_model: i.device_model,
|
|
492
|
+
$timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
493
|
+
$language: navigator.language,
|
|
494
|
+
...s
|
|
495
|
+
},
|
|
496
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
497
|
+
metadata: {
|
|
498
|
+
sdk_version: this.sdk.getOptions().getSDKVersion(),
|
|
499
|
+
sdk_library: this.sdk.getOptions().getSDKLibrary()
|
|
500
|
+
}
|
|
501
|
+
});
|
|
502
|
+
const n = this.sdk.getOptions().getFlushThreshold();
|
|
503
|
+
this.queue.size() >= n && this.flush();
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
async flush() {
|
|
507
|
+
const e = this.retry.getAll();
|
|
508
|
+
if (e.length > 0) {
|
|
509
|
+
this.retry.clearAll();
|
|
510
|
+
for (const s of e)
|
|
511
|
+
try {
|
|
512
|
+
await this.sdk.getNetwork().post(s.endpoint, s.body);
|
|
513
|
+
} catch {
|
|
514
|
+
this.retry.add(s.endpoint, s.body);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
const t = this.queue.getAll();
|
|
518
|
+
if (t.length !== 0) {
|
|
519
|
+
this.queue.clear();
|
|
520
|
+
try {
|
|
521
|
+
await this.sdk.getNetwork().post("/events", { events: t });
|
|
522
|
+
} catch {
|
|
523
|
+
this.retry.add("/events", { events: t });
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
destroy() {
|
|
528
|
+
this.flushTimer && (clearInterval(this.flushTimer), this.flushTimer = void 0);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
const H = /* @__PURE__ */ new Set(["button", "a", "input", "select", "textarea"]), z = /* @__PURE__ */ new Set([
|
|
532
|
+
"button",
|
|
533
|
+
"link",
|
|
534
|
+
"menuitem",
|
|
535
|
+
"tab",
|
|
536
|
+
"checkbox",
|
|
537
|
+
"radio",
|
|
538
|
+
"switch"
|
|
539
|
+
]), X = ["onclick", "data-action"], w = /* @__PURE__ */ new Set(["checkbox", "radio", "file", "select"]), B = 100;
|
|
540
|
+
function J(r) {
|
|
541
|
+
const e = r.tagName.toLowerCase(), t = r.getAttribute("role"), s = window.getComputedStyle(r).cursor;
|
|
542
|
+
return H.has(e) || !!t && z.has(t) || s === "pointer" || X.some((i) => r.hasAttribute(i));
|
|
543
|
+
}
|
|
544
|
+
function Z(r) {
|
|
545
|
+
const e = r.tagName.toLowerCase();
|
|
546
|
+
return w.has(e) ? !0 : e === "input" ? w.has(r.type) : !1;
|
|
547
|
+
}
|
|
548
|
+
function d(r, e) {
|
|
549
|
+
if (r === "pageview") {
|
|
550
|
+
const o = document.title?.trim(), l = window.location.pathname;
|
|
551
|
+
return o ? `User viewed "${o}" page` : `User viewed page at ${l}`;
|
|
552
|
+
}
|
|
553
|
+
if (!e)
|
|
554
|
+
return `User performed ${r}`;
|
|
555
|
+
const t = e.tagName.toLowerCase(), s = G(e), i = Q(e), n = s || i || Y(e);
|
|
556
|
+
switch (r) {
|
|
557
|
+
case "click":
|
|
558
|
+
return V(t, n, e);
|
|
559
|
+
case "submit":
|
|
560
|
+
return W(e);
|
|
561
|
+
case "change":
|
|
562
|
+
return j(t, n, e);
|
|
563
|
+
default:
|
|
564
|
+
return `User interacted with ${n || t}`;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
function V(r, e, t) {
|
|
568
|
+
const s = t.getAttribute("role");
|
|
569
|
+
if (r === "a" || s === "link")
|
|
570
|
+
return e ? `User clicked "${e}" link` : "User clicked a link";
|
|
571
|
+
if (r === "button" || s === "button")
|
|
572
|
+
return e ? `User clicked "${e}" button` : "User clicked a button";
|
|
573
|
+
if (r === "input") {
|
|
574
|
+
const i = t.type;
|
|
575
|
+
if (i === "submit")
|
|
576
|
+
return e ? `User clicked "${e}" submit button` : "User clicked submit";
|
|
577
|
+
if (i === "checkbox")
|
|
578
|
+
return e ? `User toggled "${e}" checkbox` : "User toggled a checkbox";
|
|
579
|
+
if (i === "radio")
|
|
580
|
+
return e ? `User selected "${e}" option` : "User selected a radio option";
|
|
581
|
+
}
|
|
582
|
+
return e ? `User clicked on "${e}"` : `User clicked on ${r} element`;
|
|
583
|
+
}
|
|
584
|
+
function W(r) {
|
|
585
|
+
const e = r.getAttribute("name") || r.getAttribute("id"), t = r.getAttribute("action");
|
|
586
|
+
return e ? `User submitted "${e}" form` : t ? `User submitted form to ${new URL(t, window.location.origin).pathname}` : "User submitted a form";
|
|
587
|
+
}
|
|
588
|
+
function j(r, e, t) {
|
|
589
|
+
if (r === "select")
|
|
590
|
+
return e ? `User changed "${e}" selection` : "User changed a dropdown selection";
|
|
591
|
+
if (r === "input") {
|
|
592
|
+
const s = t.type;
|
|
593
|
+
if (s === "file")
|
|
594
|
+
return e ? `User selected file for "${e}"` : "User selected a file";
|
|
595
|
+
if (s === "checkbox")
|
|
596
|
+
return e ? `User changed "${e}" checkbox` : "User changed a checkbox";
|
|
597
|
+
if (s === "radio")
|
|
598
|
+
return e ? `User selected "${e}" option` : "User selected a radio option";
|
|
599
|
+
}
|
|
600
|
+
return e ? `User changed "${e}" field` : "User changed a form field";
|
|
601
|
+
}
|
|
602
|
+
function G(r) {
|
|
603
|
+
const e = r.innerText?.trim();
|
|
604
|
+
return e && e.length > 0 && e.length <= B ? e.split(`
|
|
605
|
+
`)[0].trim() : null;
|
|
606
|
+
}
|
|
607
|
+
function Q(r) {
|
|
608
|
+
const e = r.getAttribute("aria-label");
|
|
609
|
+
if (e) return e;
|
|
610
|
+
const t = r.getAttribute("title");
|
|
611
|
+
if (t) return t;
|
|
612
|
+
const s = r.getAttribute("id");
|
|
613
|
+
if (s) {
|
|
614
|
+
const i = document.querySelector(`label[for="${s}"]`);
|
|
615
|
+
if (i?.textContent) return i.textContent.trim();
|
|
616
|
+
}
|
|
617
|
+
if (r instanceof HTMLInputElement || r instanceof HTMLTextAreaElement) {
|
|
618
|
+
const i = r.placeholder;
|
|
619
|
+
if (i) return i;
|
|
620
|
+
}
|
|
621
|
+
return null;
|
|
622
|
+
}
|
|
623
|
+
function Y(r) {
|
|
624
|
+
const e = r.getAttribute("name");
|
|
625
|
+
if (e) return e;
|
|
626
|
+
const t = r.getAttribute("id");
|
|
627
|
+
if (t && !t.match(/^[a-f0-9-]{20,}$/i))
|
|
628
|
+
return t;
|
|
629
|
+
const s = r.getAttribute("data-testid") || r.getAttribute("data-test-id");
|
|
630
|
+
return s || null;
|
|
631
|
+
}
|
|
632
|
+
class ee {
|
|
633
|
+
constructor(e) {
|
|
634
|
+
this.cleanupCallbacks = [], this.trackedChanges = /* @__PURE__ */ new WeakSet(), this.sdk = e;
|
|
635
|
+
}
|
|
636
|
+
init() {
|
|
637
|
+
this.setupAutoCapture(), this.setupOnlineListener(), this.setupShutdownListeners();
|
|
638
|
+
}
|
|
639
|
+
setupAutoCapture() {
|
|
640
|
+
if (!this.sdk.getOptions().getAutocapture())
|
|
641
|
+
return;
|
|
642
|
+
const e = (l) => {
|
|
643
|
+
const u = l.target;
|
|
644
|
+
J(u) && this.sdk.getLogger().swallow("click", () => {
|
|
645
|
+
const a = d("click", u);
|
|
646
|
+
this.sdk.getEvent().enqueue("info", a, { $autocapture: "click" });
|
|
647
|
+
});
|
|
648
|
+
}, t = (l) => {
|
|
649
|
+
const u = l.target;
|
|
650
|
+
this.sdk.getLogger().swallow("submit", () => {
|
|
651
|
+
const a = d("submit", u);
|
|
652
|
+
this.sdk.getEvent().enqueue("info", a, { $autocapture: "submit" });
|
|
653
|
+
});
|
|
654
|
+
}, s = (l) => {
|
|
655
|
+
const u = l.target;
|
|
656
|
+
Z(u) && (this.trackedChanges.has(u) || (this.trackedChanges.add(u), this.sdk.getLogger().swallow("change", () => {
|
|
657
|
+
const a = d("change", u);
|
|
658
|
+
this.sdk.getEvent().enqueue("info", a, { $autocapture: "change" });
|
|
659
|
+
})));
|
|
660
|
+
}, i = () => {
|
|
661
|
+
this.sdk.getLogger().swallow("pageview", () => {
|
|
662
|
+
const l = d("pageview");
|
|
663
|
+
this.sdk.getEvent().enqueue("info", l, { $autocapture: "pageview" });
|
|
664
|
+
});
|
|
665
|
+
};
|
|
666
|
+
i();
|
|
667
|
+
const n = history.pushState, o = history.replaceState;
|
|
668
|
+
history.pushState = (...l) => {
|
|
669
|
+
n.apply(history, l), i();
|
|
670
|
+
}, history.replaceState = (...l) => {
|
|
671
|
+
o.apply(history, l), i();
|
|
672
|
+
}, window.addEventListener("popstate", i), document.addEventListener("click", e, !0), document.addEventListener("submit", t, !0), document.addEventListener("change", s, !0), this.cleanupCallbacks.push(() => {
|
|
673
|
+
history.pushState = n, history.replaceState = o, window.removeEventListener("popstate", i), document.removeEventListener("click", e, !0), document.removeEventListener("submit", t, !0), document.removeEventListener("change", s, !0);
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
setupOnlineListener() {
|
|
677
|
+
const e = () => {
|
|
678
|
+
this.sdk.getLogger().swallow("flush", () => {
|
|
679
|
+
this.sdk.getEvent().flush();
|
|
680
|
+
});
|
|
681
|
+
};
|
|
682
|
+
window.addEventListener("online", e), this.cleanupCallbacks.push(() => {
|
|
683
|
+
window.removeEventListener("online", e);
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
setupShutdownListeners() {
|
|
687
|
+
const e = () => {
|
|
688
|
+
this.sdk.getEvent().flush();
|
|
689
|
+
}, t = () => {
|
|
690
|
+
document.visibilityState === "hidden" && this.sdk.getEvent().flush();
|
|
691
|
+
};
|
|
692
|
+
window.addEventListener("beforeunload", e), window.addEventListener("pagehide", e), typeof document < "u" && typeof document.addEventListener == "function" && document.addEventListener("visibilitychange", t), this.cleanupCallbacks.push(() => {
|
|
693
|
+
window.removeEventListener("beforeunload", e), window.removeEventListener("pagehide", e), typeof document < "u" && typeof document.removeEventListener == "function" && document.removeEventListener("visibilitychange", t);
|
|
694
|
+
});
|
|
695
|
+
}
|
|
696
|
+
destroy() {
|
|
697
|
+
this.cleanupCallbacks.forEach((e) => e()), this.cleanupCallbacks = [];
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
class te {
|
|
701
|
+
constructor() {
|
|
702
|
+
this.seen = /* @__PURE__ */ new Set();
|
|
703
|
+
}
|
|
704
|
+
capture(e, t, s) {
|
|
705
|
+
try {
|
|
706
|
+
const i = t();
|
|
707
|
+
return i instanceof Promise ? i.catch((n) => this.onCaught(e, n, s)) : i;
|
|
708
|
+
} catch (i) {
|
|
709
|
+
return this.onCaught(e, i, s);
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
swallow(e, t) {
|
|
713
|
+
this.capture(e, t, () => {
|
|
714
|
+
});
|
|
715
|
+
}
|
|
716
|
+
logError(e, t) {
|
|
717
|
+
const s = t instanceof Error ? t.message : String(t), i = t instanceof Error ? t.name : "Error";
|
|
718
|
+
this.seen.has(i) || (this.seen.add(i), console.error(`[Clonus] ${e}:`, s));
|
|
719
|
+
}
|
|
720
|
+
onCaught(e, t, s) {
|
|
721
|
+
if (t instanceof g || t instanceof h)
|
|
722
|
+
throw t;
|
|
723
|
+
return this.logError(e, t), s();
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
class se {
|
|
727
|
+
constructor(e, t, s) {
|
|
728
|
+
if (this.initialized = !1, !e || typeof e != "string" || e.trim().length < 10)
|
|
729
|
+
throw new h(
|
|
730
|
+
"Invalid API key. Must be a non-empty string with at least 10 characters."
|
|
731
|
+
);
|
|
732
|
+
this._browser = typeof window < "u" && typeof document < "u" && typeof navigator < "u", this.logger = new te(), this.user = new T(t), this.options = new y(s), this.network = new U(e, this.options.getApiUrl()), this.storage = new _(new C(), new L()), this.identity = new I(this), this.session = new $(this), this.device = new M(this), this.event = new K(this), this.autocapture = new ee(this), this._browser && this.autocapture.init();
|
|
733
|
+
}
|
|
734
|
+
getLogger() {
|
|
735
|
+
return this.logger;
|
|
736
|
+
}
|
|
737
|
+
getNetwork() {
|
|
738
|
+
return this.network;
|
|
739
|
+
}
|
|
740
|
+
getStorage() {
|
|
741
|
+
return this.storage;
|
|
742
|
+
}
|
|
743
|
+
getOptions() {
|
|
744
|
+
return this.options;
|
|
745
|
+
}
|
|
746
|
+
getUser() {
|
|
747
|
+
return this.user;
|
|
748
|
+
}
|
|
749
|
+
getDevice() {
|
|
750
|
+
return this.device;
|
|
751
|
+
}
|
|
752
|
+
getSession() {
|
|
753
|
+
return this.session;
|
|
754
|
+
}
|
|
755
|
+
getEvent() {
|
|
756
|
+
return this.event;
|
|
757
|
+
}
|
|
758
|
+
getBrowser() {
|
|
759
|
+
return this._browser;
|
|
760
|
+
}
|
|
761
|
+
async initializeAsync() {
|
|
762
|
+
return this.logger.capture(
|
|
763
|
+
"initializeAsync",
|
|
764
|
+
async () => {
|
|
765
|
+
await this.identity.initAsync(), this.initialized = !0;
|
|
766
|
+
},
|
|
767
|
+
() => (this.initialized = !0, Promise.resolve())
|
|
768
|
+
);
|
|
769
|
+
}
|
|
770
|
+
info(e, t) {
|
|
771
|
+
this._log("info", e, t);
|
|
772
|
+
}
|
|
773
|
+
warn(e, t) {
|
|
774
|
+
this._log("warn", e, t);
|
|
775
|
+
}
|
|
776
|
+
error(e, t) {
|
|
777
|
+
this._log("error", e, t);
|
|
778
|
+
}
|
|
779
|
+
_log(e, t, s) {
|
|
780
|
+
this.logger.swallow("log", () => {
|
|
781
|
+
if (!this.initialized)
|
|
782
|
+
throw new g("Must call initializeAsync() before logging.");
|
|
783
|
+
if (!t || typeof t != "string")
|
|
784
|
+
return;
|
|
785
|
+
const i = t.length > 1e3 ? t.substring(0, 1e3) : t;
|
|
786
|
+
this.event.enqueue(e, i, s ?? {});
|
|
787
|
+
});
|
|
788
|
+
}
|
|
789
|
+
async shutdown() {
|
|
790
|
+
return this.logger.capture(
|
|
791
|
+
"shutdown",
|
|
792
|
+
async () => {
|
|
793
|
+
this.autocapture.destroy(), this.event.destroy(), await this.event.flush();
|
|
794
|
+
},
|
|
795
|
+
async () => {
|
|
796
|
+
}
|
|
797
|
+
);
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
typeof window < "u" && (window.ClonusClient = se);
|
|
801
|
+
export {
|
|
802
|
+
se as ClonusClient
|
|
803
|
+
};
|
|
804
|
+
//# sourceMappingURL=index.mjs.map
|